home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / fsmake / RCS / fsmake.c,v < prev    next >
Encoding:
Text File  |  1992-11-05  |  189.5 KB  |  7,073 lines

  1. head     1.19;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    shirriff:1.19; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.19
  10. date     92.11.04.16.53.31;  author jhh;  state Exp;
  11. branches ;
  12. next     1.18;
  13.  
  14. 1.18
  15. date     90.11.01.23.24.48;  author jhh;  state Exp;
  16. branches ;
  17. next     1.17;
  18.  
  19. 1.17
  20. date     90.10.10.15.59.33;  author rab;  state Exp;
  21. branches ;
  22. next     1.16;
  23.  
  24. 1.16
  25. date     90.09.12.08.47.49;  author jhh;  state Exp;
  26. branches ;
  27. next     1.15;
  28.  
  29. 1.15
  30. date     90.02.16.16.14.31;  author jhh;  state Exp;
  31. branches ;
  32. next     1.14;
  33.  
  34. 1.14
  35. date     89.10.03.13.13.03;  author jhh;  state Exp;
  36. branches 1.14.1.1;
  37. next     1.13;
  38.  
  39. 1.13
  40. date     89.08.29.17.12.52;  author jhh;  state Exp;
  41. branches ;
  42. next     1.12;
  43.  
  44. 1.12
  45. date     89.08.29.17.03.06;  author jhh;  state Exp;
  46. branches ;
  47. next     1.11;
  48.  
  49. 1.11
  50. date     89.08.25.11.33.54;  author jhh;  state Exp;
  51. branches ;
  52. next     1.10;
  53.  
  54. 1.10
  55. date     89.08.15.16.06.57;  author jhh;  state Exp;
  56. branches ;
  57. next     1.9;
  58.  
  59. 1.9
  60. date     89.07.13.10.44.59;  author jhh;  state Exp;
  61. branches ;
  62. next     1.8;
  63.  
  64. 1.8
  65. date     89.06.16.08.46.10;  author brent;  state Exp;
  66. branches ;
  67. next     1.7;
  68.  
  69. 1.7
  70. date     89.05.22.15.15.19;  author jhh;  state Exp;
  71. branches ;
  72. next     1.6;
  73.  
  74. 1.6
  75. date     89.03.03.17.08.18;  author jhh;  state Exp;
  76. branches ;
  77. next     1.5;
  78.  
  79. 1.5
  80. date     89.01.26.11.02.18;  author jhh;  state Exp;
  81. branches ;
  82. next     1.4;
  83.  
  84. 1.4
  85. date     89.01.25.13.39.46;  author jhh;  state Exp;
  86. branches ;
  87. next     1.3;
  88.  
  89. 1.3
  90. date     89.01.06.08.16.54;  author brent;  state Exp;
  91. branches ;
  92. next     1.2;
  93.  
  94. 1.2
  95. date     88.03.31.10.09.00;  author brent;  state Exp;
  96. branches ;
  97. next     1.1;
  98.  
  99. 1.1
  100. date     87.10.20.11.01.23;  author brent;  state Exp;
  101. branches ;
  102. next     ;
  103.  
  104. 1.14.1.1
  105. date     90.07.02.22.15.18;  author jhh;  state Exp;
  106. branches ;
  107. next     ;
  108.  
  109.  
  110. desc
  111. @Make a filesystem on a disk
  112. @
  113.  
  114.  
  115. 1.19
  116. log
  117. @didn't lay things out properly on small disks
  118. @
  119. text
  120. @/* 
  121.  * fsmake.c --
  122.  *
  123.  *    Format a domain to be an empty domain.
  124.  *
  125.  * Copyright (C) 1986 Regents of the University of California
  126.  * All rights reserved.
  127.  */
  128.  
  129. #ifndef lint
  130. static char rcsid[] = "$Header: /sprite/src/admin/fsmake/RCS/fsmake.c,v 1.18 90/11/01 23:24:48 jhh Exp $ SPRITE (Berkeley)";
  131. #endif
  132.  
  133. #include "fsmake.h"
  134. #include <assert.h>
  135.  
  136. /*
  137.  * Constants settable via the command line.
  138.  */
  139. static int kbytesToFileDesc = 4;/* The ratio of kbytes to
  140.                  * the number of file descriptors */
  141. Boolean printOnly = TRUE;       /* Stop after computing the domain header
  142.                  * and just print it out. No disk writes */
  143. static Boolean overlapBlocks = FALSE;
  144.                                 /* Allow filesystem blocks to overlap track
  145.                  * boundaries.  Some disk systems can't deal. */
  146. static Boolean scsiDisk = TRUE;    /* If TRUE then simpler geometry is computed
  147.                  * that knows that SCSI controllers don't
  148.                  * think in terms of cylinders, heads, and
  149.                  * sectors.  Instead, they think in terms of
  150.                  * logical sector numbers, so we punt on finding
  151.                  * rotationally optimal block positions. */
  152. static int bootSectors = -1;    /* Number of boot sectors. */
  153. static int hostID = 0;        /* Host id to write into domain header. 
  154.                  * A host id of 0 means use local host id. */
  155. static Boolean repartition = FALSE;
  156.                                 /* If TRUE then the partition map is changed. */
  157. static Boolean reconfig = FALSE;    /* If TRUE then the disk configuration
  158.                  * is changed. */
  159. static Boolean partdisktab = FALSE;
  160.                                 /* If TRUE then read the partition map from
  161.                  * the disktab file. */
  162. static Boolean configdisktab = FALSE;
  163.                                 /* If TRUE then read the config information
  164.                  * from the disktab file, otherwise get the
  165.                  * disk size information directly from the
  166.                  * disk and compute the "best" configuration..*/
  167. static char *disktabName = "/etc/disktab"; /* Name of disktab file. */
  168. static char *sizeString = NULL;    /* Size of partitions. */
  169. static char *diskType = NULL;    /* Type of disk (e.g.rz55). */
  170. static char *labelTypeName = NULL; /* Type of label (e.g. sun). */
  171. static char *dirName = NULL;    /* Name of directory that contains files to
  172.                  * copy to the disk. */
  173. extern char *hostFileName;      /* Name of file to get host info from.  By
  174.                                    default it is /etc/spritehosts.  It is 
  175.                    defined in Host_Start.c. */
  176.  
  177. /*
  178.  * The following are used to go from a command line like
  179.  * makeFilesystem -D rsd0 -P b
  180.  * to /dev/rsd0a     - for the partition that has the disk label
  181.  * and to /dev/rsd0b    - for the partition to format.
  182.  */
  183. static char *deviceName;    /* Set to "rsd0" or "rxy1", etc. */
  184. static char *partName;        /* Set to "a", "b", "c" ... "g" */
  185. static char *rawDeviceName;    /* Set to "raw_rsd00", etc */
  186. static char defaultFirstPartName[] = "a";
  187. static char *firstPartName = defaultFirstPartName;
  188. static char defaultDevDirectory[] = "/dev";
  189. static char *devDirectory = defaultDevDirectory;
  190.  
  191. static char *hostIDString = NULL;
  192.  
  193. static Option optionArray[] = {
  194.     {OPT_STRING, "dev", (Address)&deviceName,
  195.     "Required: Name of device, eg \"rsd0\" or \"rxy1\""},
  196.     {OPT_STRING, "part", (Address)&partName,
  197.     "Required: Partition ID: (a, b, c, d, e, f, g)"},
  198.     {OPT_STRING, "rawdev", (Address)&rawDeviceName,
  199.     "Required: Name of raw device, eg \"raw_rsd00\""},
  200.     {OPT_TRUE, "scsi", (Address)&scsiDisk,
  201.     "Compute geometry for SCSI type disk (TRUE)"},
  202.     {OPT_FALSE, "noscsi", (Address)&scsiDisk,
  203.     "Compute geometry for non-SCSI disk (FALSE)"},
  204.     {OPT_TRUE, "overlap", (Address)&overlapBlocks,
  205.     "Overlap filesystem blocks across track boundaries (FALSE)"},
  206.     {OPT_INT, "ratio", (Address)&kbytesToFileDesc,
  207.     "Ratio of Kbytes to file descriptors (4)"},
  208.     {OPT_TRUE, "test", (Address)&printOnly,
  209.     "Test: print results, don't write disk (TRUE)"},
  210.     {OPT_FALSE, "write", (Address)&printOnly,
  211.     "Write the disk (FALSE)"},
  212.     {OPT_STRING, "devDir", (Address)&devDirectory,
  213.     "Name of device directory (\"/dev\")"},
  214.     {OPT_STRING, "initialPart", (Address)&firstPartName,
  215.     "Name of initial partition (\"a\")"},
  216.     {OPT_INT, "boot", (Address)&bootSectors,
  217.     "Number of boot sectors in root partition"},
  218.     {OPT_STRING, "host", (Address)&hostIDString,
  219.     "Host id or name of machine domain is attached to."},
  220.     {OPT_TRUE, "repartition", (Address)&repartition,
  221.     "Change the partitioning of the disk.  USE ONLY ON EMPTY DISKS"},
  222.     {OPT_TRUE, "reconfig", (Address) &reconfig,
  223.     "Change the disk configuration info in label. USE ONLY ON EMPTY DISKS"},
  224.     {OPT_TRUE, "configdisktab", (Address)&configdisktab,
  225.     "Reconfigure according to info in disktab file"},
  226.     {OPT_TRUE, "partdisktab", (Address)&partdisktab,
  227.     "Repartition according to info in disktab file"},
  228.     {OPT_STRING, "disktabName", (Address)&disktabName,
  229.     "Name of the disktab file"},
  230.     {OPT_STRING, "sizes", (Address)&sizeString,
  231.     "Size of partitions (as a percentage), eg \"a:25,g:75\""},
  232.     {OPT_STRING, "disktype", (Address)&diskType,
  233.     "Type of disk. Used to look up information in disktab file"},
  234.     {OPT_STRING, "labeltype", (Address)&labelTypeName,
  235.     "Type of native disk label (sun or dec)"},
  236.     {OPT_STRING, "dir", (Address)&dirName,
  237.     "Directory to copy files from"},
  238.     {OPT_STRING, "spritehosts", (Address)&hostFileName,
  239.         "File to get host information from"},
  240. };
  241. #define numOptions (sizeof(optionArray) / sizeof(Option))
  242.  
  243. /*
  244.  * Time of day when this program runs.
  245.  */
  246.  
  247. static struct timeval curTime;
  248.  
  249. static int        freeFDNum;    /* The currently free file descriptor.*/
  250. static int        freeBlockNum;    /* The currently free data block. */
  251. static unsigned char    *fdBitmapPtr;    /* Pointer to the file descriptor
  252.                      * bitmap. */
  253. static unsigned char    *cylBitmapPtr;    /* Pointer to the cylinder bit map. */
  254. static int            bytesPerCylinder;/* The number of bytes in
  255.                       * the bitmap for a cylinder.*/
  256. static Ofs_DomainHeader *headerPtr;    /* The domain header. */
  257. static Ofs_SummaryInfo *summaryPtr;    /* The summary info. */
  258.  
  259. static char *myName;
  260. /*
  261.  * Forward Declarations.
  262.  */
  263.  
  264. static void Usage _ARGS_((void));
  265. static ReturnStatus MakeFilesystem _ARGS_((int firstPartFID, int partFID,
  266.     int partition, int spriteID, Disk_Label **labelPtrPtr));
  267. static void CopyTree _ARGS_((int partFID, char *dirName, int dirFDNum,
  268.     Fsdm_FileDescriptor *dirFDPtr, int parentFDNum,
  269.     Boolean createDir, char *path));
  270. static ReturnStatus SetDomainHeader _ARGS_((Disk_Label *labelPtr,
  271.     Ofs_DomainHeader *headerPtr, int spriteID, int partition));
  272. static void SetSCSIDiskGeometry _ARGS_((Disk_Label *labelPtr,
  273.     Ofs_Geometry *geoPtr));
  274. static void SetDiskGeometry _ARGS_((Disk_Label *labelPtr,
  275.     Ofs_Geometry *geoPtr));
  276. static void SetDomainParts _ARGS_((Disk_Label *labelPtr, int partition,
  277.     Ofs_DomainHeader *headerPtr));
  278. static void SetSummaryInfo _ARGS_((Ofs_DomainHeader *headerPtr,
  279.     Ofs_SummaryInfo *summaryPtr));
  280. static ReturnStatus WriteAllFileDescs _ARGS_((int partFID,
  281.     Ofs_DomainHeader *headerPtr));
  282. static char *MakeFileDescBitmap _ARGS_((Ofs_DomainHeader *headerPtr));
  283. static ReturnStatus WriteBitmap _ARGS_((int partFID,
  284.     Ofs_DomainHeader *headerPtr));
  285. static ReturnStatus WriteRootDirectory _ARGS_((int partFID,
  286.     Ofs_DomainHeader *headerPtr, Fsdm_FileDescriptor *fdPtr));
  287. static ReturnStatus WriteLostFoundDirectory _ARGS_((int partFID,
  288.     Ofs_DomainHeader *headerPtr));
  289. static void InitDesc _ARGS_((Fsdm_FileDescriptor *fileDescPtr, int fileType,
  290.     int numBytes, int devServer, int devType, int devUnit,
  291.     int uid, int gid, int permissions, long time));
  292. static ReturnStatus AddToDirectory _ARGS_((int fid,
  293.     Ofs_DomainHeader *headerPtr, Boolean writeDisk, DirIndexInfo *dirIndexPtr,
  294.     Fslcl_DirEntry **dirEntryPtrPtr, int fileNumber, char *fileName));
  295. static ReturnStatus OpenDir _ARGS_((int fid, Ofs_DomainHeader *headerPtr,
  296.     Fsdm_FileDescriptor *fdPtr, DirIndexInfo *indexInfoPtr,
  297.     Fslcl_DirEntry **dirEntryPtrPtr));
  298. static ReturnStatus NextDirEntry _ARGS_((int fid, Ofs_DomainHeader *headerPtr,
  299.     Boolean writeDisk, DirIndexInfo *indexInfoPtr,
  300.     Fslcl_DirEntry **dirEntryPtrPtr));
  301. static ReturnStatus CloseDir _ARGS_((int fid, Ofs_DomainHeader *headerPtr,
  302.     Boolean writeDisk, DirIndexInfo *indexInfoPtr));
  303. static ReturnStatus ReadFileDesc _ARGS_((int fid, Ofs_DomainHeader *headerPtr,
  304.     int fdNum, Fsdm_FileDescriptor *fdPtr));
  305. static ReturnStatus WriteFileDesc _ARGS_((int fid, Ofs_DomainHeader *headerPtr,
  306.     int fdNum, Fsdm_FileDescriptor *fdPtr));
  307. static void CreateDir _ARGS_((Address blocks, int numBlocks,
  308.     int dot, int dotDot));
  309. static void MarkDataBitmap _ARGS_((Ofs_DomainHeader *headerPtr,
  310.     unsigned char *cylBitmapPtr, int blockNum, int numFrags));
  311. static unsigned char *ReadFileDescBitmap _ARGS_((int fid,
  312.     Ofs_DomainHeader *headerPtr));
  313. static unsigned char *ReadBitmap _ARGS_((int fid,
  314.     Ofs_DomainHeader *headerPtr));
  315. static void WriteFileDescBitmap _ARGS_((int fid, Ofs_DomainHeader *headerPtr,
  316.     unsigned char *bitmap));
  317.  
  318. extern char *getwd();
  319.  
  320.  
  321. /*
  322.  *----------------------------------------------------------------------
  323.  *
  324.  * main --
  325.  *
  326.  *    Create the required file names from the command line
  327.  *    arguments.  Then open the first partition on the disk
  328.  *    because it contains the disk label, and open the partition
  329.  *    that is to be formatted.
  330.  *
  331.  * Results:
  332.  *    None.
  333.  *
  334.  * Side effects:
  335.  *    Calls MakeFilesystem
  336.  *
  337.  *----------------------------------------------------------------------
  338.  */
  339. void
  340. main(argc, argv)
  341.     int argc;
  342.     char *argv[];
  343. {
  344.     ReturnStatus status;    /* status of system calls */
  345.     int firstPartFID;        /* File ID for first parition on the disk */
  346.     int partFID;        /* File ID for partiton to format */
  347.     int rawFID = -1;
  348.     char firstPartitionName[64];
  349.     char partitionName[64];
  350.     int partition;        /* Index of partition derived from the
  351.                  * partition name */
  352.     int spriteID;        /* Host ID of the machine with the disks */
  353.     Fs_Attributes attrs;
  354.     Disk_NativeLabelType    labelType;    
  355.     Disk_Label            *labelPtr = NULL;
  356.     int    sizes[8];
  357.     int i;
  358.  
  359.     myName = argv[0];
  360.     argc = Opt_Parse(argc, argv,optionArray, numOptions, 0);
  361.     if (argc > 1) {
  362.     Usage();
  363.     }
  364.     status = SUCCESS;
  365.     if (deviceName == (char *)0) {
  366.     fprintf(stderr,"Specify device name with -dev option\n");
  367.     status = FAILURE;
  368.     }
  369.     if (partName == (char *)0) {
  370.     fprintf(stderr,"Specify partition with -part option\n");
  371.     status = FAILURE;
  372.     }
  373.     if (bootSectors > FSDM_MAX_BOOT_SECTORS) {
  374.     fprintf(stderr,"Maximum number of boot sectors is %d.\n", 
  375.         FSDM_MAX_BOOT_SECTORS);
  376.     status = FAILURE;
  377.     }
  378.     if ((bootSectors != -1) && (bootSectors % FSDM_BOOT_SECTOR_INC != 0)) {
  379.     fprintf(stderr, "Number of boot sectors must be a multiple of %d.\n",
  380.         FSDM_BOOT_SECTOR_INC);
  381.     status = FAILURE;
  382.     }
  383.     for (i = 0; i < 8; i++) {
  384.     sizes[i] = 0;
  385.     }
  386.     if (sizeString != NULL) {
  387.     char *cPtr;
  388.     int part;
  389.     int size;
  390.     int n;
  391.     cPtr = sizeString;
  392.     while (*cPtr != '\0') {
  393.         part = (int) (*cPtr - 'a');
  394.         if (part < 0 || part > 7) {
  395.         fprintf(stderr, 
  396.         "Argument to -sizes parameter must start with partition.\n");
  397.         Usage();
  398.         }
  399.         cPtr++;
  400.         if (*cPtr != ':') {
  401.         fprintf(stderr, 
  402.         "Argument to -sizes parameter is missing a ':'.\n");
  403.         Usage();
  404.         }
  405.         cPtr++;
  406.         n = sscanf(cPtr,"%d",&size);
  407.         if (n != 1) {
  408.         fprintf(stderr, 
  409.     "Argument to -sizes parameter must have an integer following the ':'\n");
  410.         Usage();
  411.         }
  412.         sizes[part] = size;
  413.         cPtr = strchr(cPtr, ',');
  414.         if (cPtr == NULL) {
  415.         break;
  416.         }
  417.         cPtr++;
  418.     }
  419.     }
  420.     if (hostIDString != (char *) NULL) {
  421.     int        scanned;
  422.     int        temp;
  423.     Host_Entry    *entryPtr;
  424.  
  425.     scanned = sscanf(hostIDString, " %d", &temp);
  426.     if (scanned == 1) {
  427.         entryPtr = Host_ByID(temp);
  428.         if (entryPtr == NULL) {
  429.         fprintf(stderr, 
  430.             "WARNING: Host %d is not in /etc/spritehosts.\n", temp);
  431.         }
  432.         hostID = temp;
  433.     } else {
  434.         entryPtr = Host_ByName(hostIDString);
  435.         if (entryPtr == NULL) {
  436.         fprintf(stderr, 
  437.             "Host %s is not in /etc/spritehosts.\n", temp);
  438.         status = FAILURE;
  439.         }
  440.         hostID = entryPtr->id;
  441.     }
  442.     }
  443.     labelType = DISK_NO_LABEL;
  444.     if (labelTypeName != NULL) {
  445.     if (!strcasecmp(labelTypeName, "sun")) {
  446.         labelType = DISK_SUN_LABEL;
  447.     } else if (!strcasecmp(labelTypeName, "dec")) {
  448.         labelType = DISK_DEC_LABEL;
  449.     } else {
  450.         fprintf(stderr, 
  451.         "Argument to -labeltype must be \"sun\" or \"dec\"\n");
  452.         status = FAILURE;
  453.     }
  454.     }
  455.     if (status != SUCCESS) {
  456.     exit(status);
  457.     }
  458.     /*
  459.      * Gen up the name of the first partition on the disk,
  460.      * and the name of the parition that needs to be formatted.
  461.      */
  462.     sprintf(firstPartitionName, "%s/%s%c", devDirectory, deviceName,
  463.     *firstPartName);
  464.     sprintf(partitionName, "%s/%s%c", devDirectory, deviceName,
  465.     *partName);
  466.     if (rawDeviceName != NULL) {
  467.     char buffer[64];
  468.     sprintf(buffer, "%s/%s", devDirectory, rawDeviceName);
  469.     if (!printOnly) {
  470.         rawFID = open(buffer, O_RDWR);
  471.     } else {
  472.         rawFID = open(buffer, O_RDONLY);
  473.     }
  474.     if (rawFID < 0) {
  475.         fprintf(stderr, "Can't open raw device %s: ", buffer);
  476.         perror((char *) NULL);
  477.         exit(FAILURE);
  478.     }
  479.     }
  480.     if (!printOnly) {
  481.     firstPartFID = open(firstPartitionName, O_RDWR);
  482.     } else {
  483.     firstPartFID = open(firstPartitionName, O_RDONLY);
  484.     }
  485.     if (firstPartFID < 0 ) {
  486.     fprintf(stderr, "Can't open first partition %s: ", firstPartitionName);
  487.     perror((char *) NULL);
  488.     exit(FAILURE);
  489.     }
  490.     if (!printOnly) {
  491.     partFID = open(partitionName, O_RDWR);
  492.     } else {
  493.     partFID = open(partitionName, O_RDONLY);
  494.     }
  495.     if (partFID < 0) {
  496.     perror("Can't open partition to format");
  497.     exit(FAILURE);
  498.     }
  499.  
  500.     partition = partName[0] - 'a';
  501.     if (partition < 0 || partition > 7) {
  502.     fprintf(stderr,
  503.            "Can't determine partition index from the partition name\n");
  504.     exit(FAILURE);
  505.     }
  506.     if (reconfig) {
  507.     if (rawFID < 0) {
  508.         fprintf(stderr, 
  509.     "You must specify a raw device with the -reconfig flag\n");
  510.         exit(FAILURE);
  511.     }
  512.     status = Reconfig(rawFID, configdisktab, disktabName, diskType,
  513.         labelType, scsiDisk, &labelPtr);
  514.     if (status != SUCCESS) {
  515.         fprintf(stderr, "Reconfiguration of disk failed.\n");
  516.         exit(1);
  517.     }
  518.     }
  519.     if (repartition || reconfig) {
  520.     if (rawFID < 0) {
  521.         fprintf(stderr, 
  522.     "You must specify a raw device with the -repartition flag\n");
  523.         exit(FAILURE);
  524.     }
  525.     status = Repartition(rawFID, partdisktab, disktabName, diskType,
  526.         labelType, partition,
  527.         sizes, &labelPtr);
  528.     if (status != SUCCESS) {
  529.         fprintf(stderr, "Repartition of disk failed.\n");
  530.         exit(1);
  531.     }
  532.     printf("New disk label:\n");
  533.     Disk_PrintLabel(labelPtr);
  534.     status = ConfirmDiskSize(rawFID, labelPtr, sizes);
  535.     if (status != SUCCESS) {
  536.         exit(status);
  537.     }
  538.     if (!printOnly) {
  539.         status = Disk_WriteLabel(rawFID, labelPtr);
  540.         if (status != SUCCESS) {
  541.         fprintf(stderr, "Can't write label to raw device\n");
  542.         exit(status);
  543.         }
  544.     }
  545.     }
  546. #ifdef sprite  /* This stuff will not work if run under Unix. */
  547.     if (hostID == 0) {
  548.  
  549.     /*
  550.      * Determine where the disk is located so we can set the
  551.      * spriteID in the header correctly.
  552.      */
  553.     Fs_GetAttributesID(firstPartFID, &attrs);
  554.     if (attrs.devServerID == FS_LOCALHOST_ID) {
  555.         Proc_GetHostIDs((int *) NULL, &spriteID);
  556.         printf("Making filesystem for local host, ID = 0x%x\n", spriteID);
  557.     } else {
  558.         spriteID = attrs.devServerID;
  559.         printf("Making filesystem for remote host 0x%x\n", spriteID);
  560.     }
  561.     } else
  562. #endif
  563.     {
  564.     spriteID = hostID;
  565.     printf("Making filesystem for host, ID = 0x%x\n", spriteID);
  566.     }
  567.     gettimeofday(&curTime, (struct timezone *) NULL);
  568.     printf("MakeFilesystem based on 4K filesystem blocks\n");
  569.     status = MakeFilesystem(firstPartFID, partFID, partition, spriteID, 
  570.     &labelPtr);
  571.     if ((status == SUCCESS) && (dirName != NULL)) {
  572.     Fsdm_FileDescriptor    rootDesc;
  573.     printf("Copying %s to new filesystem.\n", dirName);
  574.     fdBitmapPtr = ReadFileDescBitmap(partFID, headerPtr);
  575.     cylBitmapPtr = ReadBitmap(partFID, headerPtr);
  576.     ReadFileDesc(partFID, headerPtr, FSDM_ROOT_FILE_NUMBER, &rootDesc);
  577.     CopyTree(partFID, dirName, FSDM_ROOT_FILE_NUMBER, &rootDesc,
  578.         FSDM_ROOT_FILE_NUMBER, FALSE, "/");
  579.     WriteFileDesc(partFID, headerPtr, FSDM_ROOT_FILE_NUMBER, &rootDesc);
  580.     if (!printOnly) {
  581.         status = Disk_WriteSummaryInfo(partFID, labelPtr, summaryPtr);
  582.         if (status != 0) {
  583.         perror("Summary sector write failed (2)");
  584.         exit(status);
  585.         }
  586.         WriteFileDescBitmap(partFID, headerPtr, fdBitmapPtr);
  587.         WriteBitmap(partFID, headerPtr);
  588.     }
  589.     }
  590.     fflush(stderr);
  591.     fflush(stdout);
  592.     (void)close(firstPartFID);
  593.     (void)close(partFID);
  594.     exit(status);
  595. }
  596.  
  597. /*
  598.  *----------------------------------------------------------------------
  599.  *
  600.  * Usage --
  601.  *
  602.  *    Prints out the correct command syntax and exits..
  603.  *
  604.  * Results:
  605.  *    None.
  606.  *
  607.  * Side effects:
  608.  *    The program exits.
  609.  *
  610.  *----------------------------------------------------------------------
  611.  */
  612.  
  613. static void
  614. Usage()
  615. {
  616.     Opt_PrintUsage(myName, optionArray, Opt_Number(optionArray));
  617.     exit(1);
  618. }
  619.  
  620. /*
  621.  *----------------------------------------------------------------------
  622.  *
  623.  * MakeFilesystem --
  624.  *
  625.  *    Format a disk partition, or domain, to be an empty filesystem.
  626.  *
  627.  * Results:
  628.  *    An error code.
  629.  *
  630.  * Side effects:
  631.  *    Write all over the disk partition.
  632.  *
  633.  *----------------------------------------------------------------------
  634.  */
  635. static ReturnStatus
  636. MakeFilesystem(firstPartFID, partFID, partition, spriteID, labelPtrPtr)
  637.     int firstPartFID;    /* Handle on the first partition of the disk */
  638.     int partFID;    /* Handle on the partition of the disk to format */
  639.     int partition;    /* Index of parition that is to be formatted */
  640.     int spriteID;    /* Host ID of the machine with the disks, this
  641.              * gets written on the disk and used at boot time */
  642.     Disk_Label    **labelPtrPtr; /* Ptr to ptr to disk label. */
  643. {
  644.     ReturnStatus     status;
  645.     Ofs_DomainHeader    oldDomainHeader;
  646.     Ofs_SummaryInfo    oldSummaryInfo;
  647.     Fsdm_FileDescriptor rootFD;
  648.     Fsdm_FileDescriptor *rootFDPtr = &rootFD;
  649.     Disk_Label    *labelPtr = *labelPtrPtr;
  650.  
  651.     if (labelPtr == NULL) {
  652.     labelPtr = Disk_ReadLabel(firstPartFID);
  653.     if (labelPtr == NULL) {
  654.         fprintf(stderr, "Unable to read disk label.\n");
  655.         return FAILURE;
  656.     }
  657.     }
  658.     *labelPtrPtr = labelPtr;
  659.     summaryPtr = Disk_ReadSummaryInfo(partFID, labelPtr);
  660.     if (summaryPtr != NULL) {
  661.     if (!printOnly) {
  662.         char answer[10];
  663.  
  664.         printf("\nYou are about to overwrite the \"%s\" filesystem.\n", 
  665.         summaryPtr->domainPrefix);
  666.         printf("Do you really want to do this?[y/n] ");
  667.         if (scanf("%10s",answer) != 1) {
  668.         exit(SUCCESS);
  669.         }
  670.         if ((*answer != 'y') && (*answer != 'Y')) {
  671.         return SUCCESS;
  672.         }
  673.     }
  674.     }
  675.     bzero((char *) &oldDomainHeader, sizeof(oldDomainHeader));
  676.     bzero((char *) &oldSummaryInfo, sizeof(oldSummaryInfo));
  677.     if (!printOnly) {
  678.     status = Disk_WriteDomainHeader(partFID, labelPtr, &oldDomainHeader);
  679.     if (status != SUCCESS) {
  680.         printf("Clear of old domain header failed\n");
  681.     }
  682.     status = Disk_WriteSummaryInfo(partFID, labelPtr, &oldSummaryInfo);
  683.     if (status != SUCCESS) {
  684.         printf("Clear of old summary info failed\n");
  685.     }
  686.     }
  687.     /*
  688.      * The user has specified the number of boot sectors.
  689.      */
  690.     if (bootSectors >= 0) {
  691.     labelPtr->summarySector = bootSectors + 1;
  692.     labelPtr->domainSector = bootSectors + 2;
  693.     labelPtr->numBootSectors = bootSectors;
  694.     } else {
  695.     Disk_Label *newLabelPtr;
  696.     newLabelPtr = Disk_NewLabel(labelPtr->labelType);
  697.     labelPtr->summarySector = newLabelPtr->summarySector;
  698.     labelPtr->domainSector = newLabelPtr->domainSector;
  699.     labelPtr->numBootSectors = newLabelPtr->numBootSectors;
  700.     free((char *) newLabelPtr);
  701.     }
  702.     headerPtr = (Ofs_DomainHeader *) malloc(sizeof(Ofs_DomainHeader));
  703.     status = SetDomainHeader(labelPtr, headerPtr, spriteID, partition);
  704.     if (status != SUCCESS) {
  705.     return FAILURE;
  706.     }
  707.     Disk_PrintDomainHeader(headerPtr);
  708.  
  709.     if (!printOnly) {
  710.     status = Disk_WriteLabel(partFID, labelPtr);
  711.     if (status != SUCCESS) {
  712.         perror("Disk label write failed"); 
  713.         return(status);
  714.     }
  715.     status = Disk_WriteDomainHeader(partFID, labelPtr, headerPtr);
  716.     if (status != SUCCESS) {
  717.         perror("DomainHeader write failed");
  718.         return(status);
  719.     }
  720.     }
  721.     summaryPtr = (Ofs_SummaryInfo *) malloc(DEV_BYTES_PER_SECTOR);
  722.     SetSummaryInfo(headerPtr, summaryPtr);
  723.     if (!printOnly) {
  724.     status = Disk_WriteSummaryInfo(partFID, labelPtr, summaryPtr);
  725.     if (status != SUCCESS) {
  726.         perror("Summary sector write failed");
  727.         return(status);
  728.     }
  729.     }
  730.     status = WriteAllFileDescs(partFID, headerPtr);
  731.     if (status != SUCCESS) {
  732.     perror("WriteAllFileDescs failed");
  733.     return(status);
  734.     }
  735.     status = WriteBitmap(partFID, headerPtr);
  736.     if (status != SUCCESS) {
  737.     perror("WriteBitmap failed");
  738.     return(status);
  739.     }
  740.     ReadFileDesc(partFID, headerPtr, FSDM_ROOT_FILE_NUMBER, rootFDPtr);
  741.     status = WriteRootDirectory(partFID, headerPtr, rootFDPtr);
  742.     WriteFileDesc(partFID, headerPtr, FSDM_ROOT_FILE_NUMBER, rootFDPtr);
  743.     if (status != SUCCESS) {
  744.     perror("WriteRootDirectory failed");
  745.     return(status);
  746.     }
  747.     status = WriteLostFoundDirectory(partFID, headerPtr);
  748.     if (status != SUCCESS) {
  749.     perror("WriteLostFoundDirectory failed");
  750.     return(status);
  751.     }
  752.     return(SUCCESS);
  753. }
  754.  
  755. /*
  756.  *----------------------------------------------------------------------
  757.  *
  758.  * CopyTree --
  759.  *
  760.  *    Copy the tree of files in the given directory
  761.  *    the disk table.
  762.  *
  763.  * Results:
  764.  *    A pointer to a disk info struct.
  765.  *
  766.  * Side effects:
  767.  *    Disk info struct malloc'd and initialized.  The disk header will be
  768.  *    written if is successfully set up.
  769.  *
  770.  *----------------------------------------------------------------------
  771.  */
  772. static void
  773. CopyTree(partFID, dirName, dirFDNum, dirFDPtr, parentFDNum, createDir, path)
  774.     int            partFID;    /* Handle on raw disk. */
  775.     char        *dirName;    /* Name of directory to copy. */
  776.     int            dirFDNum;    /* File number of directory. */
  777.     Fsdm_FileDescriptor    *dirFDPtr;    /* File descriptor of directory. */
  778.     int            parentFDNum;    /* File number of parent. */
  779.     Boolean        createDir;    /* Should create the directory. */
  780.     char        *path;
  781. {
  782.     DIR            *unixDirPtr;
  783.     struct direct    *unixDirEntPtr;
  784.     DirIndexInfo    indexInfo;
  785.     Fslcl_DirEntry    *spriteDirEntPtr;
  786.     char        fileName[FS_MAX_NAME_LENGTH + 1];
  787.     int            newFDNum;
  788.     Fsdm_FileDescriptor    newFD;
  789.     Fsdm_FileDescriptor    *newFDPtr;
  790.     struct    stat    statBuf;
  791.     int            followLinks;
  792.     char        pathName[1024];
  793.     char        fileBlock[FS_BLOCK_SIZE];
  794.     char        indirectBlock[FS_BLOCK_SIZE];
  795.     int            *indIndexPtr = (int *)indirectBlock;
  796.     char        *suffix;
  797.     Boolean        makeDevice;
  798.     int            devType;
  799.     int            devUnit;
  800.     int            devServer;
  801.     ReturnStatus    status;
  802.  
  803.  
  804.     /*
  805.      * Get our absolute path name so we can get back if we follow a
  806.      * symbolic link.
  807.      */
  808.     (void) getwd(pathName);
  809.  
  810.     if (chdir(dirName) < 0) {
  811.     perror(dirName);
  812.     exit(1);
  813.     }
  814.  
  815.     /*
  816.      * Get a pointer to the UNIX directory.
  817.      */
  818.     unixDirPtr = opendir(".");
  819.     if (unixDirPtr == NULL) {
  820.     fprintf(stderr, "Can't open directory %s\n", dirName);
  821.     exit(1);
  822.     }
  823.     /*
  824.      * Open the Sprite directory.
  825.      */
  826.     status = OpenDir(partFID, headerPtr, dirFDPtr, &indexInfo,&spriteDirEntPtr);
  827.     if (status != SUCCESS) {
  828.     if (chdir(pathName) < 0) {
  829.         perror(pathName);
  830.         exit(1);
  831.     }
  832.     }
  833.     /*
  834.      * See if there is a "follow.links" file in this directory.  If so
  835.      * we are supposed to follow symbolic links rather than just copying
  836.      * the links.
  837.      */
  838.     if (stat("follow.links", &statBuf) < 0) {
  839.     followLinks = 0;
  840.     } else {
  841.     printf("Following links ...\n");
  842.     followLinks = 1;
  843.     }
  844.     if (createDir) {
  845.     CreateDir(indexInfo.dirBlock, 1, dirFDNum, parentFDNum);
  846.     }
  847.  
  848.     while ((unixDirEntPtr = readdir(unixDirPtr)) != NULL) {
  849.     if (unixDirEntPtr->d_namlen == 1 && 
  850.         strncmp(unixDirEntPtr->d_name, ".", 1) == 0) {
  851.         continue;
  852.     }
  853.     if (unixDirEntPtr->d_namlen == 2 && 
  854.         strncmp(unixDirEntPtr->d_name, "..", 2) == 0) {
  855.         continue;
  856.     }
  857.     strncpy(fileName, unixDirEntPtr->d_name, unixDirEntPtr->d_namlen);
  858.     fileName[unixDirEntPtr->d_namlen] = 0;
  859.     if (followLinks) {
  860.         if (stat(fileName, &statBuf) < 0) {
  861.         perror(fileName);
  862.         exit(1);
  863.         }
  864.     } else {
  865.         if (lstat(fileName, &statBuf) < 0) {
  866.         perror(fileName);
  867.         exit(1);
  868.         }
  869.     }
  870.     makeDevice = FALSE;
  871.     suffix = strstr(fileName, DEVICE_SUFFIX);
  872.     if ((suffix != NULL) && (!strcmp(suffix, DEVICE_SUFFIX)) &&
  873.         ((statBuf.st_mode & S_GFMT) == S_GFREG)) {
  874.         FILE    *fp;
  875.         char    buffer[128];
  876.         int        ok = 0;
  877.  
  878.         fp = fopen(fileName, "r");
  879.         if (fp == NULL) {
  880.         fprintf(stderr, "WARNING: Can't open %s%s: ", pathName,
  881.             fileName);
  882.         perror((char *) NULL);
  883.         continue;
  884.         }
  885.         while (fgets(buffer, 128, fp) != NULL) {
  886.         char    tmp[128];
  887.         int    n;
  888.  
  889.         n = sscanf(buffer, " %128s", tmp);
  890.         if (n < 1 || *tmp == '#') {
  891.             continue;
  892.         }
  893.         if (sscanf(buffer, " %d %d %d", &devServer, &devType, &devUnit)
  894.             != 3) {
  895.             fprintf(stderr, 
  896.             "WARNING: Device file %s%s has bad format. Skipping.\n",
  897.             pathName, fileName);
  898.             break;
  899.         }
  900.         ok = 1;
  901.         break;
  902.         }
  903.         fclose(fp);
  904.         if (!ok) {
  905.         continue;
  906.         }
  907.         makeDevice = TRUE;
  908.         *suffix = '\0';
  909.     }
  910.     newFDNum = freeFDNum;
  911.     freeFDNum++;
  912.     MarkFDBitmap(newFDNum, fdBitmapPtr);
  913.     summaryPtr->numFreeFileDesc--;
  914.     ReadFileDesc(partFID, headerPtr, newFDNum, &newFD);
  915.     newFDPtr = &newFD;
  916.  
  917.     status = AddToDirectory(partFID, headerPtr, !printOnly, &indexInfo, 
  918.         &spriteDirEntPtr, newFDNum, fileName);
  919.     if (status != SUCCESS) {
  920.         fprintf(stderr, "%s is full\n", dirName);
  921.         break;
  922.     }
  923.     if (makeDevice) {
  924.         InitDesc(newFDPtr, FS_DEVICE, 0, devServer, devType, devUnit, 0, 0,
  925.         (int) statBuf.st_mode & 07777, curTime.tv_sec);
  926.         printf("Device: %s%s (S %d, T %d, U %d)\n", path, fileName,
  927.         devServer, devType, devUnit);
  928. #ifdef sprite
  929.     } else if ((statBuf.st_mode & S_GFMT) == S_IFPDEV) {
  930.         printf("Skipping pseudo-device %s%s\n", path, fileName);
  931. #endif
  932.     } else if ((statBuf.st_mode & S_GFMT) == S_GFREG ||
  933. #ifdef sprite
  934.            ((statBuf.st_mode & S_GFMT) == S_IFRLNK)  || 
  935. #endif
  936.            (statBuf.st_mode & S_GFMT) == S_GFLNK) {
  937.         int    fd = -1;
  938.         int    blockNum;
  939.         int    toRead;
  940.         int    len;
  941.  
  942.         blockNum = 0;
  943.         if ((statBuf.st_mode & S_GFMT) == S_GFREG) {
  944.         printf("File: %s%s\n", path, fileName);
  945.         InitDesc(newFDPtr, FS_FILE, (int) statBuf.st_size, -1, -1, -1,
  946.              0, 0, (int) statBuf.st_mode & 07777, statBuf.st_mtime);
  947.         /*
  948.          * Copy the file over.
  949.          */
  950.         fd = open(fileName, 0);
  951.         if (fd < 0) {
  952.             fprintf(stderr, "WARNING: Can't open %s%s: ", pathName,
  953.             fileName);
  954.             perror((char *) NULL);
  955.             freeFDNum--;
  956.             summaryPtr->numFreeFileDesc++;
  957.             continue;
  958.         }
  959.         len = read(fd, fileBlock, FS_BLOCK_SIZE);
  960.         if (len < 0) {
  961.             fprintf(stderr, "WARNING: Can't read %s%s: ", pathName,
  962.             fileName);
  963.             perror((char *) NULL);
  964.             freeFDNum--;
  965.             summaryPtr->numFreeFileDesc++;
  966.             continue;
  967.         }
  968.         toRead = statBuf.st_size;
  969.         } else {
  970.         len = readlink(fileName, fileBlock, FS_BLOCK_SIZE);
  971.         if (len < 0) {
  972.             fprintf(stderr, "WARNING: Can't readlink %s%s: ", pathName,
  973.             fileName);
  974.             perror((char *) NULL);
  975.             freeFDNum--;
  976.             summaryPtr->numFreeFileDesc++;
  977.             continue;
  978.         }
  979.         fileBlock[len] = '\0';
  980.         InitDesc(newFDPtr, FS_SYMBOLIC_LINK, len + 1, -1, -1, -1, 
  981.              0, 0, 0777, statBuf.st_mtime);
  982. #ifdef sprite
  983.         if ((statBuf.st_mode & S_GFMT) == S_IFRLNK) { 
  984.             printf("Remote link: %s%s\n", path, fileName);
  985.         } else {
  986.             printf("Symbolic link: %s%s -> %s\n", 
  987.                 path, fileName, fileBlock);
  988.         }
  989. #else
  990.         printf("Symbolic link: %s%s -> %s\n", 
  991.             path, fileName, fileBlock);
  992. #endif
  993.         toRead = len + 1;
  994.         }
  995.  
  996.         while (len > 0) {
  997.         if (blockNum == FSDM_NUM_DIRECT_BLOCKS) {
  998.             int    i;
  999.             int    *intPtr;
  1000.             /*
  1001.              * Must allocate an indirect block.
  1002.              */
  1003.             newFDPtr->indirect[0] =
  1004.             VirtToPhys(freeBlockNum * FS_FRAGMENTS_PER_BLOCK);
  1005.             MarkDataBitmap(headerPtr, cylBitmapPtr, freeBlockNum,
  1006.                    FS_FRAGMENTS_PER_BLOCK);
  1007.             freeBlockNum++;
  1008.             summaryPtr->numFreeKbytes -= FS_FRAGMENTS_PER_BLOCK;
  1009.             for (i = 0, intPtr = (int *)indirectBlock; 
  1010.              i < FS_BLOCK_SIZE / sizeof(int); 
  1011.              i++, intPtr++) {
  1012.              *intPtr = FSDM_NIL_INDEX;
  1013.             }
  1014.         }
  1015.         if (blockNum >= FSDM_NUM_DIRECT_BLOCKS) {
  1016.             indIndexPtr[blockNum - FSDM_NUM_DIRECT_BLOCKS] = 
  1017.                     freeBlockNum * FS_FRAGMENTS_PER_BLOCK;
  1018.             MarkDataBitmap(headerPtr, cylBitmapPtr, freeBlockNum,
  1019.                    FS_FRAGMENTS_PER_BLOCK);
  1020.             summaryPtr->numFreeKbytes -= FS_FRAGMENTS_PER_BLOCK;
  1021.         } else {
  1022.             newFDPtr->direct[blockNum] = 
  1023.                     freeBlockNum * FS_FRAGMENTS_PER_BLOCK;
  1024.             if (toRead > FS_BLOCK_SIZE) {
  1025.             MarkDataBitmap(headerPtr, cylBitmapPtr, freeBlockNum,
  1026.                        FS_FRAGMENTS_PER_BLOCK);
  1027.             summaryPtr->numFreeKbytes -= FS_FRAGMENTS_PER_BLOCK;
  1028.             } else {
  1029.             MarkDataBitmap(headerPtr, cylBitmapPtr, freeBlockNum,
  1030.                        (toRead - 1) / FS_FRAGMENT_SIZE + 1);
  1031.             summaryPtr->numFreeKbytes -= 
  1032.                     (toRead - 1) / FS_FRAGMENT_SIZE + 1;
  1033.             }
  1034.         }
  1035.         /*
  1036.          * Write the block out to disk.
  1037.          */
  1038.         if (Disk_BlockWrite(partFID, headerPtr, 
  1039.                     headerPtr->dataOffset + freeBlockNum,
  1040.                     1, (Address)fileBlock) != 0) {
  1041.             fprintf(stderr, "Couldn't write file block\n");
  1042.             exit(1);
  1043.         }
  1044.         blockNum++;
  1045.         freeBlockNum++;
  1046.         if ((statBuf.st_mode & S_GFMT) == S_GFLNK) {
  1047.             break;
  1048.         }
  1049.         toRead -= len;
  1050.         len = read(fd, fileBlock, FS_BLOCK_SIZE);
  1051.         if (len < 0) {
  1052.             perror(fileName);
  1053.             exit(1);
  1054.         }
  1055.         }
  1056.         if (newFDPtr->indirect[0] != FSDM_NIL_INDEX) {
  1057.         if (Disk_BlockWrite(partFID, headerPtr,
  1058.                 newFDPtr->indirect[0] / FS_FRAGMENTS_PER_BLOCK,
  1059.                 1, (Address)indirectBlock) != 0) {
  1060.             fprintf(stderr, "Couldn't write indirect block\n");
  1061.             exit(1);
  1062.         }
  1063.         }
  1064.         close(fd);
  1065.     } else if (statBuf.st_mode & S_GFDIR) {
  1066.         char    newPath[FS_MAX_NAME_LENGTH];
  1067.  
  1068.         /*
  1069.          * Increment the current directories link count because once
  1070.          * the child gets created it will point to the parent.
  1071.          */
  1072.         dirFDPtr->numLinks++;
  1073.         /*
  1074.          * Allocate the currently free file descriptor to this directory.
  1075.          */
  1076.         InitDesc(newFDPtr, FS_DIRECTORY, FS_BLOCK_SIZE, -1, -1, -1, 
  1077.              0, 0, (int) statBuf.st_mode & 07777, statBuf.st_mtime);
  1078.         /*
  1079.          * Give the directory one full block.  The directory will
  1080.          * be initialized by CopyTree when we call it recursively.
  1081.          */
  1082.         newFDPtr->direct[0] = freeBlockNum * FS_FRAGMENTS_PER_BLOCK;
  1083.         MarkDataBitmap(headerPtr, cylBitmapPtr, freeBlockNum,
  1084.                FS_FRAGMENTS_PER_BLOCK);
  1085.         freeBlockNum++;
  1086.         sprintf(newPath, "%s%s/", path, fileName);
  1087.         printf("Directory: %s\n", newPath);
  1088.         CopyTree(partFID, fileName, newFDNum, newFDPtr, dirFDNum, TRUE, 
  1089.         newPath);
  1090.     } else {
  1091.         fprintf(stderr, "WARNING: %s%s is not a file or directory\n",
  1092.         pathName, fileName);
  1093.         freeFDNum--;
  1094.         summaryPtr->numFreeFileDesc++;
  1095.         continue;
  1096.     }
  1097.     WriteFileDesc(partFID, headerPtr, newFDNum, newFDPtr);
  1098.  
  1099.     }
  1100.  
  1101.     CloseDir(partFID, headerPtr, !printOnly, &indexInfo);
  1102.  
  1103.     if (chdir(pathName) < 0) {
  1104.     perror(pathName);
  1105.     exit(1);
  1106.     }
  1107.     closedir(unixDirPtr);
  1108.     return;
  1109. }
  1110.  
  1111.  
  1112. /*
  1113.  *----------------------------------------------------------------------
  1114.  *
  1115.  * SetDomainHeader --
  1116.  *
  1117.  *    Compute the domain header based on the partition size and
  1118.  *    other basic disk parameters.
  1119.  *
  1120.  * Results:
  1121.  *    A return code.
  1122.  *
  1123.  * Side effects:
  1124.  *    Fill in the domain header.
  1125.  *
  1126.  *----------------------------------------------------------------------
  1127.  */
  1128. static ReturnStatus
  1129. SetDomainHeader(labelPtr, headerPtr, spriteID, partition)
  1130.     Disk_Label        *labelPtr;    /* The disk label. */
  1131.     Ofs_DomainHeader     *headerPtr;    /* Domain header to fill in */
  1132.     int         spriteID;    /* Host ID of machine with the disks */
  1133.     int         partition;    /* Index of partition to format */
  1134. {
  1135.     register Ofs_Geometry *geoPtr;/* The layout information for the disk */
  1136.  
  1137.     headerPtr->magic = OFS_DOMAIN_MAGIC;
  1138.     headerPtr->firstCylinder = labelPtr->partitions[partition].firstCylinder;
  1139.     headerPtr->numCylinders = labelPtr->partitions[partition].numCylinders;
  1140.     if (headerPtr->numCylinders <= 0) {
  1141.     fprintf(stderr, "Invalid partition size: %d cylinders.\n", 
  1142.         headerPtr->numCylinders);
  1143.     return FAILURE;
  1144.     }
  1145.     /*
  1146.      * The device.serverID from the disk is used during boot to discover
  1147.      * the host"s spriteID if reverse arp couldn't find a host ID.  The
  1148.      * unit number of disk indicates what partition of the disk this
  1149.      * domain header applies to.  For example, both the "a" and "c" partitions
  1150.      * typically start at sector zero, but only one is valid.  During boot
  1151.      * time the unit number is used to decide which partition should be
  1152.      * attached.
  1153.      */
  1154.     headerPtr->device.serverID = spriteID;
  1155.     headerPtr->device.type = -1;
  1156.     headerPtr->device.unit = partition;
  1157.     headerPtr->device.data = (ClientData)-1;
  1158.  
  1159.     geoPtr = &headerPtr->geometry;
  1160.     if (scsiDisk) {
  1161.     SetSCSIDiskGeometry(labelPtr, geoPtr);
  1162.     } else {
  1163.     SetDiskGeometry(labelPtr, geoPtr);
  1164.     }
  1165.  
  1166.     SetDomainParts(labelPtr, partition, headerPtr);
  1167.     return SUCCESS;
  1168. }
  1169.  
  1170. /*
  1171.  *----------------------------------------------------------------------
  1172.  *
  1173.  * SetSCSIDiskGeometry --
  1174.  *
  1175.  *    This computes the rotational set arrangment depending on the
  1176.  *    disk geometry.  No fancy block skewing is done.  The cylinders
  1177.  *    are divided into rotational sets that minimize the amount of
  1178.  *    wasted space.
  1179.  *
  1180.  * Results:
  1181.  *    None.
  1182.  *
  1183.  * Side effects:
  1184.  *    Fill in the geometry struct.
  1185.  *
  1186.  *----------------------------------------------------------------------
  1187.  */
  1188. static void
  1189. SetSCSIDiskGeometry(labelPtr, geoPtr)
  1190.     register Disk_Label        *labelPtr;    /* The disk label. */
  1191.     register Ofs_Geometry     *geoPtr;    /* Fancy geometry information */
  1192. {
  1193.     register int index;        /* Array index */
  1194.     int blocksPerCyl;        /* The number of blocks in a cylinder */
  1195.  
  1196.     geoPtr->numHeads = labelPtr->numHeads;
  1197.     geoPtr->sectorsPerTrack = labelPtr->numSectors;
  1198.  
  1199.     blocksPerCyl = geoPtr->sectorsPerTrack * geoPtr->numHeads /
  1200.         DISK_SECTORS_PER_BLOCK;
  1201.  
  1202.     printf("Disk has %d tracks/cyl, %d sectors/track\n",
  1203.         geoPtr->numHeads, geoPtr->sectorsPerTrack);
  1204.     printf("%d 4K Blocks fit on a cylinder with %d 512 byte sectors wasted\n",
  1205.         blocksPerCyl, geoPtr->sectorsPerTrack * geoPtr->numHeads - 
  1206.         blocksPerCyl * DISK_SECTORS_PER_BLOCK);
  1207.     geoPtr->rotSetsPerCyl = OFS_SCSI_MAPPING;
  1208.     geoPtr->blocksPerRotSet = 0;
  1209.     geoPtr->blocksPerCylinder = blocksPerCyl;
  1210.     geoPtr->tracksPerRotSet = 0;
  1211.     /*
  1212.      * Don't use rotational sorting anyway.
  1213.      */
  1214.     for (index = 0 ; index < OFS_MAX_ROT_POSITIONS ; index++) {
  1215.     geoPtr->sortedOffsets[index] = -1;
  1216.     }
  1217. }
  1218.  
  1219. /*
  1220.  *----------------------------------------------------------------------
  1221.  *
  1222.  * SetDiskGeometry --
  1223.  *
  1224.  *    This computes the rotational set arrangment depending on the
  1225.  *    disk geometry.  The basic rules for this are that filesystem blocks
  1226.  *    are skewed on successive tracks, and that the skewing pattern
  1227.  *    repeats in either 2 or 4 tracks.  This is specific to the fact that
  1228.  *    filesystem blocks are 4Kbytes.  This means that one disk track
  1229.  *    contains N/4 filesystem blocks and that one sector per track
  1230.  *    is wasted if there are an odd number of sectors per track.
  1231.  *
  1232.  * Results:
  1233.  *    None.
  1234.  *
  1235.  * Side effects:
  1236.  *    Fill in the geometry struct.
  1237.  *
  1238.  *----------------------------------------------------------------------
  1239.  */
  1240. static void
  1241. SetDiskGeometry(labelPtr, geoPtr)
  1242.     register Disk_Label        *labelPtr;    /* The disk label. */
  1243.     register Ofs_Geometry     *geoPtr;    /* Fancy geometry information */
  1244. {
  1245.     register int index;        /* Array index */
  1246.     int numBlocks;        /* The number of blocks in a rotational set */
  1247.     int tracksPerSet = 0;    /* Total number of tracks in a rotational set */
  1248.     int numTracks;        /* The number of tracks in the set so far */
  1249.     int extraSectors;        /* The number of leftover sectors in a track */
  1250.     int offset;            /* The sector offset within a track */
  1251.     int startingOffset;        /* The offset of the first block in a track */
  1252.     int offsetIncrement = 0;    /* The skew of the starting offset on each
  1253.                  * successive track of the rotational set */
  1254.     Boolean overlap = FALSE;    /* TRUE if filesystem blocks overlap tracks */
  1255.  
  1256.     geoPtr->numHeads = labelPtr->numHeads;
  1257.     geoPtr->sectorsPerTrack = labelPtr->numSectors;
  1258.  
  1259.     /*
  1260.      * Figure out some basic parameters of the rotational set.  The number
  1261.      * of tracks in the set is either 2 or 4.  If 2, then the blocks on
  1262.      * successive tracks are skewed by 1/2 a filesystem block.  If 4,
  1263.      * blocks are skewed by 1/4 block.  A 4 track rotational set is best
  1264.      * becasue there are more rotational positions.  If, however, it
  1265.      * causes 2 or 3 wasted tracks at the end, or if blocks naturally
  1266.      * overlap by 1/2 block, then only 2 tracks per rotational set are
  1267.      * used.
  1268.      */
  1269.     switch(geoPtr->numHeads % 4) {
  1270.     case 0:
  1271.     case 1: {
  1272.         extraSectors = geoPtr->sectorsPerTrack % DISK_SECTORS_PER_BLOCK;
  1273.         if (extraSectors < DISK_SECTORS_PER_BLOCK/4) {
  1274.         /*
  1275.          * Not enough extra sectors to overlap blocks onto the
  1276.          * next track.  The blocks will fit evenly on a track,
  1277.          * but the blocks on the following tracks will be skewed.
  1278.          */
  1279.         tracksPerSet = 4;
  1280.         overlap = FALSE;
  1281.         offsetIncrement = DISK_SECTORS_PER_BLOCK/4;
  1282.         } else if (extraSectors < DISK_SECTORS_PER_BLOCK/2) {
  1283.         /*
  1284.          * Enough to overlap the first 1/4 block onto the next track.
  1285.          */
  1286.         tracksPerSet = 4;
  1287.         overlap = TRUE;
  1288.         offsetIncrement = DISK_SECTORS_PER_BLOCK * 3/4;
  1289.         } else if (extraSectors < DISK_SECTORS_PER_BLOCK * 3/4) {
  1290.         /*
  1291.          * Enough to overlap 1/2 block.
  1292.          */
  1293.         tracksPerSet = 2;
  1294.         overlap = TRUE;
  1295.         offsetIncrement = DISK_SECTORS_PER_BLOCK/2;
  1296.         } else {
  1297.         /*
  1298.          * Enough to overlap 3/4 block.
  1299.          */
  1300.         tracksPerSet = 4;
  1301.         overlap = TRUE;
  1302.         offsetIncrement = DISK_SECTORS_PER_BLOCK/4;
  1303.         }
  1304.         break;
  1305.     }
  1306.     case 2:
  1307.     case 3: {
  1308.         /*
  1309.          * Instead of wasting 2 or 3 tracks to have a 4 track rotational
  1310.          * set, the rotational set is only 2 tracks long.  Also see if
  1311.          * the blocks naturally overlap by 1/2 block.
  1312.          */
  1313.         tracksPerSet = 2;
  1314.         offsetIncrement = DISK_SECTORS_PER_BLOCK/2;
  1315.         if ((geoPtr->sectorsPerTrack % DISK_SECTORS_PER_BLOCK) <
  1316.               DISK_SECTORS_PER_BLOCK/2) {
  1317.         overlap = FALSE;
  1318.         } else {
  1319.         overlap = TRUE;
  1320.         }
  1321.     }
  1322.     }
  1323.     if (!overlapBlocks) {
  1324.     overlap = FALSE;
  1325.     offsetIncrement = 0;
  1326.     }
  1327.     printf("overlap %s, offsetIncrement %d\n", (overlap ? "TRUE" : "FALSE"),
  1328.               offsetIncrement);
  1329.     /*
  1330.      * Determine rotational position of the blocks in the rotational set.
  1331.      */
  1332.     extraSectors = geoPtr->sectorsPerTrack;
  1333.     startingOffset = 0;
  1334.     offset = startingOffset;
  1335.     for (numBlocks = 0, numTracks = 0 ; ; ) {
  1336.     if (extraSectors >= DISK_SECTORS_PER_BLOCK) {
  1337.         /*
  1338.          * Ok to fit in another filesystem block on this track.
  1339.          */
  1340.         geoPtr->blockOffset[numBlocks] = offset;
  1341.         numBlocks++;    
  1342.         offset += DISK_SECTORS_PER_BLOCK;
  1343.         extraSectors -= DISK_SECTORS_PER_BLOCK;
  1344.     } else {
  1345.         /*
  1346.          * The current block has to take up room on the next track.
  1347.          */
  1348.         numTracks++;
  1349.         if (numTracks < tracksPerSet) {
  1350.         /*
  1351.          * Ok to go to the next track.
  1352.          */
  1353.         startingOffset += offsetIncrement;
  1354.         if (overlap) {
  1355.             /*
  1356.              * If the current block can overlap to the next track,
  1357.              * use the current offset.  Because of the overlap
  1358.              * there are fewer sectors available for blocks on
  1359.              * the next track.
  1360.              */
  1361.             geoPtr->blockOffset[numBlocks] = offset;
  1362.             numBlocks++;
  1363.             extraSectors = geoPtr->sectorsPerTrack - startingOffset;
  1364.         }
  1365.         offset = startingOffset + numTracks * geoPtr->sectorsPerTrack;
  1366.         if (!overlap) {
  1367.             /*
  1368.              * If no overlap the whole next track is available.
  1369.              */
  1370.             extraSectors = geoPtr->sectorsPerTrack;
  1371.         }
  1372.         } else {
  1373.         /*
  1374.          * Done.
  1375.          */
  1376.         for (index = numBlocks; index < OFS_MAX_ROT_POSITIONS; index++){
  1377.             geoPtr->blockOffset[index] = -1;
  1378.         }
  1379.         break;
  1380.         }
  1381.     }
  1382.     }
  1383.     geoPtr->blocksPerRotSet = numBlocks;
  1384.     geoPtr->tracksPerRotSet = tracksPerSet;
  1385.     geoPtr->rotSetsPerCyl = geoPtr->numHeads / tracksPerSet;
  1386.     geoPtr->blocksPerCylinder = numBlocks * geoPtr->rotSetsPerCyl;
  1387.  
  1388.     /*
  1389.      * Now the rotational positions have to be sorted so that rotationally
  1390.      * optimal blocks can be found.  The array sortedOffsets is set so
  1391.      * that the I'th element has the index into blockOffset which contains
  1392.      * the I'th rotational position, eg.
  1393.      *    blockOffset    sortedOffsets
  1394.      *        0 (+0)        0
  1395.      *        8 (+0)        2
  1396.      *        4 (+17)        1
  1397.      *       12 (+17)        3
  1398.      */
  1399.  
  1400.     offsetIncrement = DISK_SECTORS_PER_BLOCK / tracksPerSet;
  1401.     for (index = 0 ; index < OFS_MAX_ROT_POSITIONS ; index++) {
  1402.     geoPtr->sortedOffsets[index] = -1;
  1403.     }
  1404.     for (index = 0 ; index < numBlocks ; index++) {
  1405.     offset = geoPtr->blockOffset[index] % geoPtr->sectorsPerTrack;
  1406.     geoPtr->sortedOffsets[offset/offsetIncrement] = index;
  1407.     }
  1408. }
  1409.  
  1410. /*
  1411.  *----------------------------------------------------------------------
  1412.  *
  1413.  * SetDomainParts --
  1414.  *
  1415.  *    Set up the way the domain is divided into 4 areas:  the bitmap
  1416.  *    for the file descriptors, the file descriptors, the bitmap for
  1417.  *    the data blocks, and the data blocks.
  1418.  *
  1419.  * Results:
  1420.  *    The geometry information is completed.
  1421.  *
  1422.  * Side effects:
  1423.  *    None.
  1424.  *
  1425.  *----------------------------------------------------------------------
  1426.  */
  1427. static void
  1428. SetDomainParts(labelPtr, partition, headerPtr)
  1429.     register Disk_Label        *labelPtr;    /* The disk label. */
  1430.     int partition;
  1431.     register Ofs_DomainHeader *headerPtr;
  1432. {
  1433.     register Ofs_Geometry *geoPtr;
  1434.     int numFiles;        /* Number of files computed from the size */
  1435.     int numBlocks;        /* Number of blocks in the partition.  This
  1436.                  * is computed and then dolled out to the
  1437.                  * different things stored in the partition */
  1438.     int offset;            /* Block offset within partition */
  1439.     int bitmapBytes;        /* Number of bytes taken up by a bitmap */
  1440.     int reservedBlocks;        /* Number of blocks reserved at beginning
  1441.                  * of partition */
  1442.     int maxSector;
  1443.     int numCylinders;
  1444.     int bytesPerCylinder;
  1445.  
  1446.     /*
  1447.      * Set aside a number of blocks at the begining of the partition for
  1448.      * things like the super block, the boot program, and the domain header.
  1449.      */
  1450.     geoPtr = &headerPtr->geometry;
  1451.     maxSector = labelPtr->labelSector;
  1452.     maxSector = Max(maxSector,labelPtr->bootSector + labelPtr->numBootSectors);
  1453.     maxSector = Max(maxSector,labelPtr->summarySector
  1454.     + labelPtr->numSummarySectors);
  1455.     maxSector = Max(maxSector,labelPtr->domainSector
  1456.     + labelPtr->numDomainSectors);
  1457.     numCylinders = labelPtr->partitions[partition].numCylinders;
  1458.     if (scsiDisk) {
  1459.     /*
  1460.      * For a scsi disk just reserve whole cylinders.
  1461.      */
  1462.     int cylinders;
  1463.     cylinders = maxSector / (geoPtr->sectorsPerTrack * geoPtr->numHeads);
  1464.     if ((maxSector % (geoPtr->sectorsPerTrack * geoPtr->numHeads)) != 0) {
  1465.         cylinders++;
  1466.     }
  1467.     reservedBlocks = cylinders * geoPtr->blocksPerCylinder;
  1468.     numBlocks = geoPtr->blocksPerCylinder * numCylinders - reservedBlocks;
  1469.      } else {
  1470.     /*
  1471.      * If we are using rotational sets then reserve whole sets.
  1472.      */
  1473.     int sets;
  1474.     sets = maxSector / (geoPtr->tracksPerRotSet * geoPtr->sectorsPerTrack);
  1475.     if ((maxSector % (geoPtr->tracksPerRotSet * geoPtr->sectorsPerTrack)) 
  1476.     != 0) {
  1477.         sets++;
  1478.     }
  1479.     reservedBlocks = sets * geoPtr->blocksPerRotSet;
  1480.     numBlocks = geoPtr->blocksPerCylinder * numCylinders - reservedBlocks;
  1481.     }
  1482.     printf("Reserving %d blocks for domain header, etc.\n", reservedBlocks);
  1483.     /*
  1484.      * Determine the number of filesystem blocks available and compute a
  1485.      * first guess at the number of file descriptors.  If at the end of
  1486.      * the computation things don't fit nicely, then the number of files
  1487.      * is changed and the computation is repeated.
  1488.      */
  1489.     numFiles = 0;
  1490.     do {
  1491.     if (numFiles == 0) {
  1492.         numFiles = numBlocks * DISK_KBYTES_PER_BLOCK / kbytesToFileDesc;
  1493.     }
  1494.     numFiles          &= ~(FSDM_FILE_DESC_PER_BLOCK-1);
  1495.     offset              = reservedBlocks;
  1496.  
  1497.     assert(numFiles > 0);
  1498.     headerPtr->fdBitmapOffset = offset;
  1499.     bitmapBytes          = (numFiles - 1) / BITS_PER_BYTE + 1;
  1500.     headerPtr->fdBitmapBlocks = (bitmapBytes - 1) / FS_BLOCK_SIZE + 1;
  1501.     numBlocks          -= headerPtr->fdBitmapBlocks;
  1502.     offset              += headerPtr->fdBitmapBlocks;
  1503.  
  1504.     headerPtr->fileDescOffset = offset;
  1505.     headerPtr->numFileDesc      = numFiles;
  1506.     numBlocks          -= numFiles / FSDM_FILE_DESC_PER_BLOCK;
  1507.     offset              += numFiles / FSDM_FILE_DESC_PER_BLOCK;
  1508.     /*
  1509.      * The data blocks will start on a cylinder.  Try the next
  1510.      * cylinder boundary after the start of the bitmap. If the
  1511.      * bitmap won't fit in a cylinder then steal a cylinder from the
  1512.      * data blocks.
  1513.      */
  1514.     headerPtr->bitmapOffset      = offset;
  1515.     headerPtr->dataOffset      = ((offset-1) / geoPtr->blocksPerCylinder + 1)
  1516.                      * geoPtr->blocksPerCylinder;
  1517.     headerPtr->dataBlocks      = headerPtr->numCylinders *
  1518.                       geoPtr->blocksPerCylinder -
  1519.                       headerPtr->dataOffset;
  1520.     bytesPerCylinder      = (geoPtr->blocksPerCylinder + 1) / 2;
  1521.     bitmapBytes          = bytesPerCylinder * (headerPtr->dataBlocks / 
  1522.                     geoPtr->blocksPerCylinder); 
  1523.  
  1524.     headerPtr->bitmapBlocks      = (bitmapBytes - 1) / FS_BLOCK_SIZE + 1;
  1525.     while (headerPtr->bitmapBlocks > 
  1526.         headerPtr->dataOffset - headerPtr->bitmapOffset) {
  1527.         /*
  1528.          * If the bit map blocks won't fit in the number cylinders
  1529.          * we've allocated to them then we need to
  1530.          * steal a cylinder from the data blocks.
  1531.          */
  1532.         headerPtr->dataOffset += geoPtr->blocksPerCylinder;
  1533.         headerPtr->dataBlocks -= geoPtr->blocksPerCylinder;
  1534.         bitmapBytes -= geoPtr->blocksPerCylinder * bytesPerCylinder;
  1535.         bitmapBytes          = bytesPerCylinder * (headerPtr->dataBlocks / 
  1536.                     geoPtr->blocksPerCylinder); 
  1537.         headerPtr->bitmapBlocks = (bitmapBytes - 1) / FS_BLOCK_SIZE + 1;
  1538.     }
  1539.     /*
  1540.      * Check the size of the bit map against space available for it
  1541.      * between the end of the file descriptors and the start of the
  1542.      * data blocks.
  1543.      */
  1544.     if (headerPtr->dataOffset - headerPtr->bitmapOffset <
  1545.         headerPtr->bitmapBlocks) {
  1546.         int numBlocksNeeded;
  1547.         /*
  1548.          * Need more blocks to hold the bitmap.  Reduce the number
  1549.          * of file descriptors to get the blocks and re-iterate.
  1550.          */
  1551.         numBlocksNeeded = headerPtr->bitmapBlocks -
  1552.         (headerPtr->dataOffset - headerPtr->bitmapOffset);
  1553.         numFiles -= numBlocksNeeded * FSDM_FILE_DESC_PER_BLOCK;
  1554.     } else if (headerPtr->dataOffset - headerPtr->bitmapOffset >
  1555.             headerPtr->bitmapBlocks) {
  1556.         int extraBlocks;
  1557.         /*
  1558.          * There are extra blocks between the end of the file descriptors
  1559.          * and the start of the bitmap.  Increase the number of
  1560.          * file descriptors and re-iterate.
  1561.          */
  1562.         extraBlocks = headerPtr->dataOffset - headerPtr->bitmapOffset -
  1563.             headerPtr->bitmapBlocks;
  1564.         numFiles += extraBlocks * FSDM_FILE_DESC_PER_BLOCK;
  1565.     }
  1566.     } while (headerPtr->dataOffset - headerPtr->bitmapOffset !=
  1567.         headerPtr->bitmapBlocks);
  1568.     headerPtr->dataCylinders    = headerPtr->dataBlocks /
  1569.                   geoPtr->blocksPerCylinder ;
  1570. }
  1571.  
  1572. /*
  1573.  *----------------------------------------------------------------------
  1574.  *
  1575.  * SetSummaryInfo --
  1576.  *
  1577.  *    Initialize the summary information for the domain.  
  1578.  *
  1579.  * Results:
  1580.  *    A return code.
  1581.  *
  1582.  * Side effects:
  1583.  *    Fill in the summary info.
  1584.  *
  1585.  *----------------------------------------------------------------------
  1586.  */
  1587. static void
  1588. SetSummaryInfo(headerPtr, summaryPtr)
  1589.     Ofs_DomainHeader *headerPtr;    /* Domain header to summarize */
  1590.     Ofs_SummaryInfo *summaryPtr;    /* Summary info to fill in */
  1591. {
  1592.  
  1593.     bzero((Address)summaryPtr, sizeof(Ofs_SummaryInfo));
  1594.  
  1595.     strcpy(summaryPtr->domainPrefix, "(new domain)");
  1596.     /*
  1597.      * 20 KB is already allocated, 4 for the root directory,
  1598.      * 8 for lost+found, and 8 for .fscheck.out
  1599.      */
  1600.     summaryPtr->numFreeKbytes = headerPtr->dataBlocks * (FS_BLOCK_SIZE / 1024)
  1601.                 - 20;
  1602.     /*
  1603.      * 5 file descriptors are already used, 0 and 1 are reserved,
  1604.      * 2 is for the root, 3 is for lost+found, and 4 is for .fscheck.out
  1605.      */
  1606.     summaryPtr->numFreeFileDesc = headerPtr->numFileDesc - 5;
  1607.     /*
  1608.      * The summary state field is unused.
  1609.      */
  1610.     summaryPtr->state = 0;
  1611.     /*
  1612.      * The domain number under which this disk partition is mounted is
  1613.      * recorded on disk so servers re-attach disks under the same "name".
  1614.      * We set it to the special value so it gets a new number assigned
  1615.      * when it is first attached.
  1616.      */
  1617.     summaryPtr->domainNumber = -1;
  1618.     /*
  1619.      * The flags field is used to record whether or not the disk has been
  1620.      * safely "sync"ed to disk upon shutdown.
  1621.      */
  1622.     summaryPtr->flags = 0;
  1623.     summaryPtr->attachSeconds = 0;
  1624.     summaryPtr->detachSeconds = 0;
  1625.     summaryPtr->fixCount = 0;
  1626. }
  1627.  
  1628. /*
  1629.  *----------------------------------------------------------------------
  1630.  *
  1631.  * WriteAllFileDescs --
  1632.  *
  1633.  *    Write out all of the file descriptors to disk.
  1634.  *
  1635.  * Results:
  1636.  *    SUCCESS if the descriptors were written, FAILURE otherwise.
  1637.  *
  1638.  * Side effects:
  1639.  *    None.
  1640.  *
  1641.  *----------------------------------------------------------------------
  1642.  */
  1643. static ReturnStatus
  1644. WriteAllFileDescs(partFID, headerPtr)
  1645.     int partFID;    /* File handle for partition to format */
  1646.     register Ofs_DomainHeader *headerPtr;
  1647. {
  1648.     ReturnStatus status;
  1649.     char *bitmap;
  1650.     char block[FS_BLOCK_SIZE];
  1651.     register Fsdm_FileDescriptor *fileDescPtr;
  1652.     register int index;
  1653.     int j;
  1654.  
  1655.     bitmap = MakeFileDescBitmap(headerPtr);
  1656.     if (!printOnly) {
  1657.     status = Disk_BlockWrite(partFID, headerPtr, headerPtr->fdBitmapOffset,
  1658.                 headerPtr->fdBitmapBlocks, (Address)bitmap);
  1659.     if (status != SUCCESS) {
  1660.         printf("Couldn't write bitmap\n");
  1661.         return(status);
  1662.     }
  1663.     }
  1664.     /*
  1665.      * Make the first block of file descriptors.  This contains some
  1666.      * canned file descriptors for the root, bad block file, the
  1667.      * lost and found directory and fscheck's output file.  
  1668.      */
  1669.     bzero(block, FS_BLOCK_SIZE);
  1670.     for (index = 0;
  1671.          index < FSDM_FILE_DESC_PER_BLOCK;
  1672.      index++ ) {
  1673.     fileDescPtr = (Fsdm_FileDescriptor *)((int)block +
  1674.                        index * FSDM_MAX_FILE_DESC_SIZE);
  1675.     fileDescPtr->magic = FSDM_FD_MAGIC;
  1676.     if (index < FSDM_BAD_BLOCK_FILE_NUMBER) {
  1677.         fileDescPtr->flags = FSDM_FD_RESERVED;
  1678.     } else if (index == FSDM_BAD_BLOCK_FILE_NUMBER) {
  1679.         InitDesc(fileDescPtr, FS_FILE, 0, -1, -1, -1, 0, 0, 0, 
  1680.         curTime.tv_sec);
  1681.     } else if (index == FSDM_ROOT_FILE_NUMBER) {
  1682.         InitDesc(fileDescPtr, FS_DIRECTORY, FS_BLOCK_SIZE, -1, -1, -1, 0,
  1683.             0, 0755, curTime.tv_sec);
  1684.         /*
  1685.          * Place the data in the first file system block.
  1686.          */
  1687.         fileDescPtr->direct[0] = 0;
  1688.     } else if (index == FSDM_LOST_FOUND_FILE_NUMBER) {
  1689.         InitDesc(fileDescPtr, FS_DIRECTORY, 2 * FS_BLOCK_SIZE,-1, -1, -1, 0,
  1690.             0, 0777, curTime.tv_sec);
  1691.         for (j = 0; j < OFS_NUM_LOST_FOUND_BLOCKS ; j++) {
  1692.         fileDescPtr->direct[j] = FS_FRAGMENTS_PER_BLOCK 
  1693.             * (j + 1);
  1694.         }
  1695.     } else if (index == FSDM_LOST_FOUND_FILE_NUMBER+1) {
  1696.         InitDesc(fileDescPtr, FS_FILE, 2 * FS_BLOCK_SIZE, -1, -1, -1, 0,
  1697.             0, 0755, curTime.tv_sec);
  1698.         for (j = 0; j < 2 ; j++) {
  1699.         fileDescPtr->direct[j] = FS_FRAGMENTS_PER_BLOCK 
  1700.             * (j + 1 + OFS_NUM_LOST_FOUND_BLOCKS);
  1701.         }
  1702.     } else {
  1703.         fileDescPtr->flags = FSDM_FD_FREE;
  1704.     }
  1705.     }
  1706.     if (!printOnly) {
  1707.     /*
  1708.      * Write out the first, specially hand crafted, block of file
  1709.      * descriptors.
  1710.      */
  1711.     status = Disk_BlockWrite(partFID, headerPtr, headerPtr->fileDescOffset,
  1712.                     1, (Address)block);
  1713.     if (status != SUCCESS) {
  1714.         return(status);
  1715.     }
  1716.     /*
  1717.      * Redo the block for the remaining file descriptors
  1718.      */
  1719.     bzero(block, FS_BLOCK_SIZE);
  1720.     for (index = 0;
  1721.          index < FSDM_FILE_DESC_PER_BLOCK;
  1722.          index++ ) {
  1723.         fileDescPtr = (Fsdm_FileDescriptor *)((int)block + index *
  1724.                            FSDM_MAX_FILE_DESC_SIZE);
  1725.         fileDescPtr->magic = FSDM_FD_MAGIC;
  1726.         fileDescPtr->flags = FSDM_FD_FREE;
  1727.     }
  1728.     /*
  1729.      * Write out the remaining file descriptors.
  1730.      */
  1731.     for (index = FSDM_FILE_DESC_PER_BLOCK;
  1732.          index < headerPtr->numFileDesc;
  1733.          index += FSDM_FILE_DESC_PER_BLOCK) {
  1734.         status = Disk_BlockWrite(partFID, headerPtr,
  1735.              headerPtr->fileDescOffset + (index/FSDM_FILE_DESC_PER_BLOCK),
  1736.              1, (Address)block);
  1737.         if (status != SUCCESS) {
  1738.         return(status);
  1739.         }
  1740.     }
  1741.     } else {
  1742.     status = SUCCESS;
  1743.     }
  1744.     return(status);
  1745. }
  1746.  
  1747. /*
  1748.  *----------------------------------------------------------------------
  1749.  *
  1750.  * MakeFileDescBitmap --
  1751.  *
  1752.  *    Compute out the bitmap for file descriptor array to disk.
  1753.  *
  1754.  * Results:
  1755.  *    None.
  1756.  *
  1757.  * Side effects:
  1758.  *    None.
  1759.  *
  1760.  *----------------------------------------------------------------------
  1761.  */
  1762. static char *
  1763. MakeFileDescBitmap(headerPtr)
  1764.     register Ofs_DomainHeader *headerPtr;
  1765. {
  1766.     register char *bitmap;
  1767.     register int index;
  1768.  
  1769.     /*
  1770.      * Allocate and initialize the bitmap to all 0"s to mean all free.
  1771.      */
  1772.     bitmap = (char *)malloc((unsigned) headerPtr->fdBitmapBlocks *
  1773.                  FS_BLOCK_SIZE);
  1774.     bzero((Address)bitmap, headerPtr->fdBitmapBlocks * FS_BLOCK_SIZE);
  1775.  
  1776.     /*
  1777.      * Reserve file descriptors 0, 1, 2, 3, and 4. File number 0 is not used at 
  1778.      * all in the filesystem.  File number 1 is for the file with bad blocks.
  1779.      * File number 2 (FSDM_ROOT_FILE_NUMBER) is the domain's root directory.
  1780.      * File number 3 (FS_LOST_FOUND_NUMBER) is the directory where lost
  1781.      * files are stored.
  1782.      * File number 4 is for fscheck's output.
  1783.      *
  1784.      * IF THIS CHANGES remember to fix SetSummaryInfo
  1785.      */
  1786.     bitmap[0] |= 0xf8;
  1787.     freeFDNum = 5;
  1788.     /*
  1789.      * Set the bits in the map at the end that don't correspond to
  1790.      * any existing file descriptors.
  1791.      */
  1792.     index = headerPtr->numFileDesc / BITS_PER_BYTE;
  1793.     if (headerPtr->numFileDesc % BITS_PER_BYTE) {
  1794.     register int bitIndex;
  1795.     /*
  1796.      * Take care the last byte that only has part of its bits set.
  1797.      */
  1798.     for (bitIndex = headerPtr->numFileDesc % BITS_PER_BYTE;
  1799.          bitIndex < BITS_PER_BYTE;
  1800.          bitIndex++) {
  1801.         bitmap[index] |= 1 << ((BITS_PER_BYTE - 1) - bitIndex);
  1802.     }
  1803.     index++;
  1804.     }
  1805.     index++;
  1806.     for ( ; index < headerPtr->fdBitmapBlocks * FS_BLOCK_SIZE; index++) {
  1807.     bitmap[index] = 0xff;
  1808.     }
  1809.  
  1810.     if (printOnly) {
  1811.     Disk_PrintFileDescBitmap(headerPtr, bitmap);
  1812.     }
  1813.     return(bitmap);
  1814. }
  1815.  
  1816. /*
  1817.  *----------------------------------------------------------------------
  1818.  *
  1819.  * WriteBitmap --
  1820.  *
  1821.  *    Write out the bitmap for the data blocks.  This knows that the
  1822.  *    first 4K is allocated to the root directory, 8K is
  1823.  *    allocated to lost and found, and 8K to .fscheck.out.
  1824.  *
  1825.  * Results:
  1826.  *    A return code from the writes.
  1827.  *
  1828.  * Side effects:
  1829.  *    Write the bitmap.
  1830.  *
  1831.  *----------------------------------------------------------------------
  1832.  */
  1833. static ReturnStatus
  1834. WriteBitmap(partFID, headerPtr)
  1835.     int partFID;
  1836.     register Ofs_DomainHeader *headerPtr;
  1837. {
  1838.     ReturnStatus status;
  1839.     char *bitmap;
  1840.  
  1841.     bitmap = (char *)malloc((unsigned) headerPtr->bitmapBlocks * FS_BLOCK_SIZE);
  1842.     bzero(bitmap, headerPtr->bitmapBlocks * FS_BLOCK_SIZE);
  1843.     /*
  1844.      * Set the bits corresponding to the 4K used for the root directory,
  1845.      * the 8K reserved for lost and found, and the 8K reserved for
  1846.      * .fscheck.out.
  1847.      *   ________
  1848.      *    |0______7|    Bits are numbered like this in a byte.
  1849.      *
  1850.      * IF THIS CHANGES remember to fix SetSummaryInfo()
  1851.      */
  1852.     bitmap[0] |= 0xff;
  1853.     bitmap[1] |= 0xff;
  1854.     bitmap[2] |= 0xf0;
  1855.     freeBlockNum = 5;
  1856.     if (printOnly) {
  1857.     Disk_PrintDataBlockBitmap(headerPtr, bitmap);
  1858.     status = SUCCESS;
  1859.     } else {
  1860.     status = Disk_BlockWrite(partFID, headerPtr, headerPtr->bitmapOffset,
  1861.                 headerPtr->bitmapBlocks, (Address)bitmap);
  1862.     }
  1863.     return(status);
  1864. }
  1865.  
  1866. /*
  1867.  *----------------------------------------------------------------------
  1868.  *
  1869.  * WriteRootDirectory --
  1870.  *
  1871.  *    Write the data blocks of the root directory.
  1872.  *
  1873.  * Results:
  1874.  *    A return code from the writes.
  1875.  *
  1876.  * Side effects:
  1877.  *    Write the root directory"s data block.
  1878.  *
  1879.  *----------------------------------------------------------------------
  1880.  */
  1881. static ReturnStatus
  1882. WriteRootDirectory(partFID, headerPtr, fdPtr)
  1883.     int             partFID;    /* Raw disk handle. */
  1884.     register Ofs_DomainHeader     *headerPtr;    /* Domain header. */
  1885.     Fsdm_FileDescriptor        *fdPtr;        /* Root file desc */
  1886. {
  1887.     ReturnStatus     status;
  1888.     char         block[FS_BLOCK_SIZE];
  1889.     Fslcl_DirEntry     *dirEntryPtr;
  1890.     int         i;
  1891.     DirIndexInfo    indexInfo;
  1892.  
  1893.     CreateDir(block, 1, FSDM_ROOT_FILE_NUMBER, FSDM_ROOT_FILE_NUMBER);
  1894.     if (printOnly) {
  1895.     int offset;
  1896.     printf("Root Directory\n");
  1897.     offset = 0;
  1898.     for (i = 0; i < 4; i++) {
  1899.         dirEntryPtr = (Fslcl_DirEntry *)((int)block + offset);
  1900.         Disk_PrintDirEntry(dirEntryPtr);
  1901.         offset += dirEntryPtr->recordLength;
  1902.     }
  1903.     } else {
  1904.     status = Disk_BlockWrite(partFID, headerPtr, headerPtr->dataOffset,
  1905.         1, block);
  1906.     if (status != 0) {
  1907.         fprintf(stderr, "WriteRootDirectory: Couldn't write directory\n");
  1908.     }
  1909.     }
  1910.     status = OpenDir(partFID, headerPtr, fdPtr, &indexInfo, &dirEntryPtr);
  1911.     if (status != SUCCESS) {
  1912.     fprintf(stderr, "Can't open root file descriptor\n");
  1913.     return status;
  1914.     }
  1915.     status = AddToDirectory(partFID, headerPtr, !printOnly, &indexInfo, 
  1916.             &dirEntryPtr, FSDM_LOST_FOUND_FILE_NUMBER, 
  1917.             "lost+found");
  1918.     if (status != SUCCESS) {
  1919.     fprintf(stderr, "Can't add lost+found to root directory.\n");
  1920.     return status;
  1921.     }
  1922.     fdPtr->numLinks++;
  1923.     status = AddToDirectory(partFID, headerPtr, !printOnly, &indexInfo,
  1924.             &dirEntryPtr, FSDM_LOST_FOUND_FILE_NUMBER + 1, 
  1925.             ".fscheck.out");
  1926.     if (status != SUCCESS) {
  1927.     fprintf(stderr, "Can't add .fscheck.out to root directory.\n");
  1928.     return status;
  1929.     }
  1930.     CloseDir(partFID, headerPtr, !printOnly, &indexInfo);
  1931.     return(status);
  1932. }
  1933.  
  1934. /*
  1935.  *----------------------------------------------------------------------
  1936.  *
  1937.  * WriteLostFoundDirectory --
  1938.  *
  1939.  *    Write the data blocks of the lost and found directory.
  1940.  *
  1941.  * Results:
  1942.  *    A return code from the writes.
  1943.  *
  1944.  * Side effects:
  1945.  *    Write the root directory"s data block.
  1946.  *
  1947.  *----------------------------------------------------------------------
  1948.  */
  1949. static ReturnStatus
  1950. WriteLostFoundDirectory(partFID, headerPtr)
  1951.     int partFID;
  1952.     register Ofs_DomainHeader *headerPtr;
  1953. {
  1954.     ReturnStatus     status = SUCCESS;
  1955.     char         block[OFS_NUM_LOST_FOUND_BLOCKS * FS_BLOCK_SIZE];
  1956.     Fslcl_DirEntry     *dirEntryPtr;
  1957.     int         i;
  1958.  
  1959.     CreateDir(block, OFS_NUM_LOST_FOUND_BLOCKS, FSDM_LOST_FOUND_FILE_NUMBER, 
  1960.     FSDM_ROOT_FILE_NUMBER);
  1961.     if (printOnly) {
  1962.     int offset;
  1963.     printf("lost+found Directory\n");
  1964.     offset = 0;
  1965.     for (i = 0; i < 4; i++) {
  1966.         dirEntryPtr = (Fslcl_DirEntry *)((int)block + offset);
  1967.         Disk_PrintDirEntry(dirEntryPtr);
  1968.         offset += dirEntryPtr->recordLength;
  1969.     }
  1970.     } else {
  1971.     status = Disk_BlockWrite(partFID, headerPtr, headerPtr->dataOffset + 1,
  1972.             OFS_NUM_LOST_FOUND_BLOCKS, block);
  1973.     if (status != 0) {
  1974.         fprintf(stderr, 
  1975.         "WriteLostFoundDirectory: Couldn't write directory\n");
  1976.     }
  1977.     }
  1978.     return(status);
  1979. }
  1980.  
  1981. /*
  1982.  *----------------------------------------------------------------------
  1983.  *
  1984.  * InitDesc --
  1985.  *
  1986.  *    Set up a file descriptor as allocated.
  1987.  *
  1988.  * Results:
  1989.  *    None.
  1990.  *
  1991.  * Side effects:
  1992.  *    File descriptor fields filled in.
  1993.  *
  1994.  *----------------------------------------------------------------------
  1995.  */
  1996. static void
  1997. InitDesc(fileDescPtr, fileType, numBytes, devServer, devType, devUnit, uid,
  1998.     gid, permissions, time)
  1999.     Fsdm_FileDescriptor    *fileDescPtr;
  2000.     int            fileType;
  2001.     int            numBytes;
  2002.     int            devServer;
  2003.     int            devType;
  2004.     int            devUnit;
  2005.     int            uid;
  2006.     int            gid;
  2007.     int            permissions;
  2008.     long        time;
  2009. {
  2010.     int        index;
  2011.  
  2012.     fileDescPtr->flags = FSDM_FD_ALLOC;
  2013.     fileDescPtr->fileType = fileType;
  2014.     fileDescPtr->permissions = permissions;
  2015.     fileDescPtr->uid = uid;
  2016.     fileDescPtr->gid = gid;
  2017.     fileDescPtr->lastByte = numBytes - 1;
  2018.     fileDescPtr->firstByte = -1;
  2019.     if (fileType == FS_DIRECTORY) {
  2020.     fileDescPtr->numLinks = 2;
  2021.     } else {
  2022.     fileDescPtr->numLinks = 1;
  2023.     }
  2024.     fileDescPtr->devServerID = devServer;
  2025.     fileDescPtr->devType = devType;
  2026.     fileDescPtr->devUnit = devUnit;
  2027.  
  2028.     /*
  2029.      * Set the time stamps.  This assumes that universal time,
  2030.      * not local time, is used for time stamps.
  2031.      */
  2032.     fileDescPtr->createTime = (int) time;
  2033.     fileDescPtr->accessTime = (int) time;
  2034.     fileDescPtr->descModifyTime = (int) time;
  2035.     fileDescPtr->dataModifyTime = (int) time;
  2036.  
  2037.     /*
  2038.      * Place the data in the first filesystem block.
  2039.      */
  2040.     for (index = 0; index < FSDM_NUM_DIRECT_BLOCKS ; index++) {
  2041.     fileDescPtr->direct[index] = FSDM_NIL_INDEX;
  2042.     }
  2043.     for (index = 0; index < FSDM_NUM_INDIRECT_BLOCKS ; index++) {
  2044.     fileDescPtr->indirect[index] = FSDM_NIL_INDEX;
  2045.     }
  2046.     if (numBytes > 0) {
  2047.     int    numBlocks;
  2048.  
  2049.     numBlocks = (numBytes - 1) / FS_BLOCK_SIZE + 1;
  2050.     if (numBlocks > FSDM_NUM_DIRECT_BLOCKS) {
  2051.         fileDescPtr->numKbytes = (numBlocks + 1) * (FS_BLOCK_SIZE / 1024);
  2052.     } else {
  2053.         fileDescPtr->numKbytes = (numBytes + 1023) / 1024;
  2054.     }
  2055.     } else {
  2056.     fileDescPtr->numKbytes = 0;
  2057.     }
  2058.  
  2059.     fileDescPtr->version = 1;
  2060. }
  2061.  
  2062. /*
  2063.  *----------------------------------------------------------------------
  2064.  *
  2065.  * AddToDirectory --
  2066.  *
  2067.  *    Add the file descriptor to a directory.  
  2068.  *
  2069.  * Results:
  2070.  *    SUCCESS if the desciptor was added ok, FAILURE otherwise
  2071.  *
  2072.  * Side effects:
  2073.  *    The directory is modified to contain the file.
  2074.  *
  2075.  *----------------------------------------------------------------------
  2076.  */
  2077. static ReturnStatus
  2078. AddToDirectory(fid, headerPtr, writeDisk, dirIndexPtr, dirEntryPtrPtr, 
  2079.     fileNumber, fileName)
  2080.     int            fid;        /* Handle on raw disk. */
  2081.     Ofs_DomainHeader     *headerPtr;    /* Domain header. */
  2082.     Boolean        writeDisk;    /* Write the disk? */
  2083.     DirIndexInfo    *dirIndexPtr;    /* Index information. */
  2084.     Fslcl_DirEntry    **dirEntryPtrPtr; /* Directory entry. */
  2085.     int             fileNumber;    /* File number to add. */
  2086.     char         *fileName;    /* Name of file to add. */
  2087. {
  2088.     int             nameLength;
  2089.     int             recordLength;
  2090.     int             leftOver;
  2091.     int            oldRecLength;
  2092.     Fslcl_DirEntry    *dirEntryPtr;
  2093.     ReturnStatus     status = SUCCESS;
  2094.  
  2095.     dirEntryPtr = *dirEntryPtrPtr;
  2096.  
  2097.     nameLength = strlen(fileName);
  2098.     recordLength = Fslcl_DirRecLength(nameLength);
  2099.  
  2100.     while (1) {
  2101.     if (dirEntryPtr->fileNumber != 0) {
  2102.         oldRecLength = Fslcl_DirRecLength(dirEntryPtr->nameLength);
  2103.         leftOver = dirEntryPtr->recordLength - oldRecLength;
  2104.         if (leftOver >= recordLength) {
  2105.         dirEntryPtr->recordLength = oldRecLength;
  2106.         dirEntryPtr = 
  2107.             (Fslcl_DirEntry *) ((int) dirEntryPtr + oldRecLength);
  2108.         dirEntryPtr->recordLength = leftOver;
  2109.         dirIndexPtr->dirOffset += oldRecLength;
  2110.         } else {
  2111.         status = NextDirEntry(fid, headerPtr, writeDisk,
  2112.                 dirIndexPtr, &dirEntryPtr);
  2113.         if (status != SUCCESS) {
  2114.             fprintf(stderr, "Can't add to directory\n");
  2115.             return status;
  2116.         }
  2117.         continue;
  2118.         }
  2119.     } else if (dirEntryPtr->recordLength < recordLength) {
  2120.         status = NextDirEntry(fid, headerPtr, writeDisk,
  2121.             dirIndexPtr, &dirEntryPtr);
  2122.         if (status != SUCCESS) {
  2123.         fprintf(stderr, "Can't add to directory\n");
  2124.         return status;
  2125.         }
  2126.         continue;
  2127.     }
  2128.     dirEntryPtr->fileNumber = fileNumber;
  2129.     dirEntryPtr->nameLength = nameLength;
  2130.     (void)strcpy(dirEntryPtr->fileName, fileName);
  2131.     leftOver = dirEntryPtr->recordLength - recordLength;
  2132.     if (leftOver > FSLCL_DIR_ENTRY_HEADER) {
  2133.         dirEntryPtr->recordLength = recordLength;
  2134.         dirEntryPtr =(Fslcl_DirEntry *) ((int) dirEntryPtr + recordLength);
  2135.         dirEntryPtr->fileNumber = 0;
  2136.         dirEntryPtr->recordLength = leftOver;
  2137.         dirIndexPtr->dirOffset += recordLength;
  2138.     } else {
  2139.         status = NextDirEntry(fid, headerPtr, writeDisk, 
  2140.                 dirIndexPtr, &dirEntryPtr);
  2141.         if (status != SUCCESS) {
  2142.         fprintf(stderr, "Can't add to directory\n");
  2143.         return status;
  2144.         }
  2145.     }
  2146.     *dirEntryPtrPtr = dirEntryPtr;
  2147.     return status;
  2148.     }
  2149. }
  2150.  
  2151. /*
  2152.  *----------------------------------------------------------------------
  2153.  *
  2154.  * OpenDir --
  2155.  *
  2156.  *    Set up the structure to allow moving through the given directory.
  2157.  *
  2158.  * Results:
  2159.  *    SUCCESS if the open was successful, FAILURE otherwise
  2160.  *
  2161.  * Side effects:
  2162.  *    The index structure is set up and *dirEntryPtrPtr set to point to
  2163.  *    the first directory entry.
  2164.  *
  2165.  *----------------------------------------------------------------------
  2166.  */
  2167. static ReturnStatus
  2168. OpenDir(fid, headerPtr, fdPtr, indexInfoPtr, dirEntryPtrPtr)
  2169.     int            fid;        /* Handle on raw disk. */
  2170.     Ofs_DomainHeader     *headerPtr;    /* Domain header. */
  2171.     Fsdm_FileDescriptor    *fdPtr;        /* The file descriptor for the
  2172.                      * directory. */
  2173.     DirIndexInfo     *indexInfoPtr;    /* Index info struct */
  2174.     Fslcl_DirEntry    **dirEntryPtrPtr; /* Current directory entry */
  2175. {
  2176.  
  2177.     *dirEntryPtrPtr = NULL;
  2178.     if (fdPtr->lastByte == -1) {
  2179.     /*
  2180.      * Empty directory.
  2181.      */
  2182.     return SUCCESS;
  2183.     } else if ((fdPtr->lastByte + 1) % FSLCL_DIR_BLOCK_SIZE != 0) {
  2184.     fprintf(stderr, "Directory not multiple of directory block size.\n");
  2185.     return FAILURE;
  2186.     } else if (fdPtr->fileType != FS_DIRECTORY) {
  2187.     fprintf(stderr, "OpenDir: Not a directory\n");
  2188.     return FAILURE;
  2189.     }
  2190.  
  2191.     /*
  2192.      * Initialize the index structure.
  2193.      */
  2194.     indexInfoPtr->fdPtr = fdPtr;
  2195.     indexInfoPtr->blockNum = 0;
  2196.     indexInfoPtr->blockAddr = fdPtr->direct[0] / FS_FRAGMENTS_PER_BLOCK + 
  2197.                   headerPtr->dataOffset;
  2198.     /*
  2199.      * Read in the directory block.
  2200.      */
  2201.     if (fdPtr->lastByte != FS_BLOCK_SIZE - 1) {
  2202.     fprintf(stderr, "We created a directory that's not 4K?\n");
  2203.     return FAILURE;
  2204.     }
  2205.     if (Disk_BlockRead(fid, headerPtr,
  2206.                indexInfoPtr->blockAddr,
  2207.                1, indexInfoPtr->dirBlock) < 0) {
  2208.     fprintf(stderr, "OpenDir: Read failed block %d\n",
  2209.             indexInfoPtr->blockAddr);
  2210.     return FAILURE;
  2211.     } 
  2212.     indexInfoPtr->dirOffset = 0;
  2213.     *dirEntryPtrPtr = (Fslcl_DirEntry *) indexInfoPtr->dirBlock;
  2214.     return SUCCESS;
  2215. }
  2216.  
  2217.  
  2218. /*
  2219.  *----------------------------------------------------------------------
  2220.  *
  2221.  * NextDirEntry --
  2222.  *
  2223.  *    Get a pointer to the next directory entry.
  2224.  *
  2225.  * Results:
  2226.  *    SUCCESS if the next entry was found ok, FAILURE otherwise
  2227.  *
  2228.  * Side effects:
  2229.  *    The index structure is modified and *dirEntryPtrPtr set to point
  2230.  *    to the next directory entry.
  2231.  *
  2232.  *----------------------------------------------------------------------
  2233.  */
  2234. static ReturnStatus
  2235. NextDirEntry(fid, headerPtr, writeDisk, indexInfoPtr, dirEntryPtrPtr)
  2236.     int            fid;        /* Handle on raw disk. */
  2237.     Ofs_DomainHeader     *headerPtr;    /* Domain header. */
  2238.     Boolean        writeDisk;    /* Write the disk? */
  2239.     DirIndexInfo     *indexInfoPtr;    /* Index information. */
  2240.     Fslcl_DirEntry    **dirEntryPtrPtr; /* Current directory entry */
  2241. {
  2242.     Fslcl_DirEntry    *dirEntryPtr;    
  2243.  
  2244.     dirEntryPtr = *dirEntryPtrPtr;
  2245.     indexInfoPtr->dirOffset += dirEntryPtr->recordLength;
  2246.     if (indexInfoPtr->dirOffset < FS_BLOCK_SIZE) {
  2247.     /*
  2248.      * The next directory entry is in the current block.
  2249.      */
  2250.     *dirEntryPtrPtr = (Fslcl_DirEntry *)
  2251.             &(indexInfoPtr->dirBlock[indexInfoPtr->dirOffset]);
  2252.     return SUCCESS;
  2253.     } else {
  2254.     Fsdm_FileDescriptor    *fdPtr;
  2255.     int            i;
  2256.  
  2257.     printf("Adding new block to directory ...\n");
  2258.  
  2259.     /*
  2260.      * Write out the current block and set up the next one.
  2261.      */
  2262.     if (writeDisk) {
  2263.         if (Disk_BlockWrite(fid, headerPtr, indexInfoPtr->blockAddr,
  2264.                 1, indexInfoPtr->dirBlock) < 0) {
  2265.         fprintf(stderr, "NextDirEntry: Write failed block %d\n",
  2266.                 indexInfoPtr->blockAddr);
  2267.         return FAILURE;
  2268.         }
  2269.     }
  2270.     fdPtr = indexInfoPtr->fdPtr;
  2271.     fdPtr->lastByte += FS_BLOCK_SIZE;
  2272.     fdPtr->numKbytes += FS_FRAGMENTS_PER_BLOCK;
  2273.     indexInfoPtr->blockNum++;
  2274.     fdPtr->direct[indexInfoPtr->blockNum] = 
  2275.                 freeBlockNum * FS_FRAGMENTS_PER_BLOCK;
  2276.     MarkDataBitmap(headerPtr, cylBitmapPtr, freeBlockNum,
  2277.                FS_FRAGMENTS_PER_BLOCK);
  2278.     indexInfoPtr->blockAddr = freeBlockNum + headerPtr->dataOffset;
  2279.     freeBlockNum++;
  2280.     for (i = 0, dirEntryPtr = (Fslcl_DirEntry *)indexInfoPtr->dirBlock; 
  2281.          i < FS_BLOCK_SIZE / FSLCL_DIR_BLOCK_SIZE;
  2282.      i++,dirEntryPtr=(Fslcl_DirEntry *)((unsigned)dirEntryPtr+FSLCL_DIR_BLOCK_SIZE)) {
  2283.         dirEntryPtr->fileNumber = 0;
  2284.         dirEntryPtr->recordLength = FSLCL_DIR_BLOCK_SIZE;
  2285.         dirEntryPtr->nameLength = 0;
  2286.     }
  2287.     indexInfoPtr->dirOffset = 0;
  2288.     *dirEntryPtrPtr = (Fslcl_DirEntry *) indexInfoPtr->dirBlock;
  2289.     return SUCCESS;
  2290.     }
  2291. }
  2292.  
  2293.  
  2294. /*
  2295.  *----------------------------------------------------------------------
  2296.  *
  2297.  * CloseDir --
  2298.  *
  2299.  *    Flushes the current directory block to disk, if necessary.
  2300.  *
  2301.  * Results:
  2302.  *    SUCCESS if the directory was closed ok, FAILURE otherwise
  2303.  *
  2304.  * Side effects:
  2305.  *    Stuff is written to disk.
  2306.  *
  2307.  *----------------------------------------------------------------------
  2308.  */
  2309. static ReturnStatus
  2310. CloseDir(fid, headerPtr, writeDisk, indexInfoPtr)
  2311.     int            fid;        /* Handle on raw disk. */
  2312.     Ofs_DomainHeader     *headerPtr;    /* Domain header. */
  2313.     Boolean        writeDisk;    /* Write the disk? */
  2314.     DirIndexInfo     *indexInfoPtr;    /* Index information. */
  2315. {
  2316.  
  2317.     if (writeDisk) {
  2318.     if (Disk_BlockWrite(fid, headerPtr, indexInfoPtr->blockAddr,
  2319.                 1, indexInfoPtr->dirBlock) < 0) {
  2320.         fprintf(stderr, "CloseDir: Write (2) failed block %d\n",
  2321.                 indexInfoPtr->blockAddr);
  2322.         return FAILURE;
  2323.     }
  2324.     }
  2325.     return SUCCESS;
  2326. }
  2327.  
  2328. /*
  2329.  *----------------------------------------------------------------------
  2330.  *
  2331.  * ReadFileDesc --
  2332.  *
  2333.  *    Return the given file descriptor.
  2334.  *
  2335.  * Results:
  2336.  *    SUCCESS if file descriptor was read ok, FAILURE otherwise
  2337.  *
  2338.  * Side effects:
  2339.  *    The file descriptor struct is filled in.
  2340.  *
  2341.  *----------------------------------------------------------------------
  2342.  */
  2343. static ReturnStatus
  2344. ReadFileDesc(fid, headerPtr, fdNum, fdPtr)
  2345.     int            fid;        /* Handle on raw disk. */
  2346.     Ofs_DomainHeader     *headerPtr;    /* Domain header. */
  2347.     int            fdNum;        /* File number. */
  2348.     Fsdm_FileDescriptor    *fdPtr;        /* Place to store fd. */
  2349. {
  2350.     static char        block[FS_BLOCK_SIZE];
  2351.     int            blockNum;
  2352.     int            offset;
  2353.  
  2354.     blockNum = headerPtr->fileDescOffset + fdNum / FSDM_FILE_DESC_PER_BLOCK;
  2355.     offset = (fdNum & (FSDM_FILE_DESC_PER_BLOCK - 1)) * FSDM_MAX_FILE_DESC_SIZE;
  2356.     if (Disk_BlockRead(fid, headerPtr, blockNum, 1, 
  2357.                (Address) block) < 0) {
  2358.     fprintf(stderr, "ReadFileDesc: Read failed\n");
  2359.     return FAILURE;
  2360.     }
  2361.     bcopy((Address)&block[offset], (Address)fdPtr, sizeof(Fsdm_FileDescriptor));
  2362.     return SUCCESS;
  2363. }
  2364.  
  2365.  
  2366. /*
  2367.  *----------------------------------------------------------------------
  2368.  *
  2369.  * WriteFileDesc --
  2370.  *
  2371.  *    Write the given file descriptor.
  2372.  *
  2373.  * Results:
  2374.  *    SUCCESS if the write was successful, FAILURE otherwise
  2375.  *
  2376.  * Side effects:
  2377.  *    Stuff is written to disk.
  2378.  *
  2379.  *----------------------------------------------------------------------
  2380.  */
  2381. static ReturnStatus
  2382. WriteFileDesc(fid, headerPtr, fdNum, fdPtr)
  2383.     int            fid;        /* Handle on raw disk. */
  2384.     Ofs_DomainHeader     *headerPtr;    /* Domain header. */
  2385.     int            fdNum;        /* File number. */
  2386.     Fsdm_FileDescriptor    *fdPtr;        /* Place to store fd. */
  2387. {
  2388.     static char        block[FS_BLOCK_SIZE];
  2389.     int            blockNum;
  2390.     int            offset;
  2391.  
  2392.     blockNum = headerPtr->fileDescOffset + fdNum / FSDM_FILE_DESC_PER_BLOCK;
  2393.     offset = (fdNum & (FSDM_FILE_DESC_PER_BLOCK - 1)) * FSDM_MAX_FILE_DESC_SIZE;
  2394.     if (Disk_BlockRead(fid, headerPtr, blockNum, 1, 
  2395.                (Address) block) < 0) {
  2396.     fprintf(stderr, "WriteFileDesc: Read failed\n");
  2397.     return FAILURE;
  2398.     }
  2399.     bcopy((Address)fdPtr, (Address)&block[offset], sizeof(Fsdm_FileDescriptor));
  2400.     if (Disk_BlockWrite(fid, headerPtr, blockNum, 1, 
  2401.                (Address) block) < 0) {
  2402.     fprintf(stderr, "WriteFileDesc: Write failed\n");
  2403.     return FAILURE;
  2404.     }
  2405.     return SUCCESS;
  2406. }
  2407. /*
  2408.  *----------------------------------------------------------------------
  2409.  *
  2410.  * CreateDir --
  2411.  *
  2412.  *    Create a directory out of file system blocks.
  2413.  *
  2414.  * Results:
  2415.  *    None.
  2416.  *
  2417.  * Side effects:
  2418.  *    File system block set up as a directory.
  2419.  *
  2420.  *----------------------------------------------------------------------
  2421.  */
  2422. static void
  2423. CreateDir(blocks, numBlocks, dot, dotDot)
  2424.     Address    blocks;        /* Blocks to create directory in. */
  2425.     int        numBlocks;    /* Number of blocks. */
  2426.     int        dot;        /* File number of directory. */
  2427.     int        dotDot;        /* File number of parent. */
  2428. {
  2429.     Fslcl_DirEntry    *dirEntryPtr;
  2430.     char    *fileName;
  2431.     int        offset;
  2432.     int        length;
  2433.     int        i;
  2434.  
  2435.     dirEntryPtr = (Fslcl_DirEntry *)blocks;
  2436.     fileName = ".";
  2437.     length = strlen(fileName);
  2438.     dirEntryPtr->fileNumber = dot;
  2439.     dirEntryPtr->recordLength = Fslcl_DirRecLength(length);
  2440.     dirEntryPtr->nameLength = length;
  2441.     strcpy(dirEntryPtr->fileName, fileName);
  2442.     offset = dirEntryPtr->recordLength;
  2443.  
  2444.     dirEntryPtr = (Fslcl_DirEntry *)((int)blocks + offset);
  2445.     fileName = "..";
  2446.     length = strlen(fileName);
  2447.     dirEntryPtr->fileNumber = dotDot;
  2448.     dirEntryPtr->recordLength = FSLCL_DIR_BLOCK_SIZE - offset;
  2449.     dirEntryPtr->nameLength = length;
  2450.     strcpy(dirEntryPtr->fileName, fileName);
  2451.     /*
  2452.      * Fill out the rest of the directory with empty blocks.
  2453.      */
  2454.     for (dirEntryPtr = (Fslcl_DirEntry *)&blocks[FSLCL_DIR_BLOCK_SIZE], i = 1; 
  2455.      i < (FS_BLOCK_SIZE * numBlocks) / FSLCL_DIR_BLOCK_SIZE;
  2456.      i++,dirEntryPtr=(Fslcl_DirEntry *)((int)dirEntryPtr + FSLCL_DIR_BLOCK_SIZE)) {
  2457.      dirEntryPtr->fileNumber = 0;
  2458.      dirEntryPtr->recordLength = FSLCL_DIR_BLOCK_SIZE;
  2459.      dirEntryPtr->nameLength = 0;
  2460.     }
  2461. }
  2462. int fragMasks[FS_FRAGMENTS_PER_BLOCK + 1] = {0x0, 0x08, 0x0c, 0x0e, 0x0f};
  2463.  
  2464.  
  2465. /*
  2466.  *----------------------------------------------------------------------
  2467.  *
  2468.  * MarkDataBitmap --
  2469.  *
  2470.  *    Mark the appropriate bits in the data block bitmap.
  2471.  *
  2472.  * Results:
  2473.  *    None.
  2474.  *
  2475.  * Side effects:
  2476.  *    Data block marked.
  2477.  *
  2478.  *----------------------------------------------------------------------
  2479.  */
  2480. static void
  2481. MarkDataBitmap(headerPtr, cylBitmapPtr, blockNum, numFrags)
  2482.     Ofs_DomainHeader    *headerPtr;
  2483.     unsigned char    *cylBitmapPtr;
  2484.     int            blockNum;
  2485.     int            numFrags;
  2486. {
  2487.     unsigned char    *bitmapPtr;
  2488.  
  2489.     bitmapPtr = GetBitmapPtr(headerPtr, cylBitmapPtr, blockNum);
  2490.     if ((blockNum % headerPtr->geometry.blocksPerCylinder) & 0x1) {
  2491.     *bitmapPtr |= fragMasks[numFrags];
  2492.     } else {
  2493.     *bitmapPtr |= fragMasks[numFrags] << 4;
  2494.     }
  2495. }
  2496.  
  2497. /*
  2498.  *----------------------------------------------------------------------
  2499.  *
  2500.  * ReadFileDescBitmap --
  2501.  *
  2502.  *    Read in the file descriptor bitmap.
  2503.  *
  2504.  * Results:
  2505.  *    A pointer to the file descriptor bit map.
  2506.  *
  2507.  * Side effects:
  2508.  *    Memory allocated for the bit map.
  2509.  *
  2510.  *----------------------------------------------------------------------
  2511.  */
  2512. static unsigned char *
  2513. ReadFileDescBitmap(fid, headerPtr)
  2514.     int            fid;        /* Handle on raw disk. */
  2515.     Ofs_DomainHeader     *headerPtr;    /* Domain header. */
  2516. {
  2517.     register unsigned char *bitmap;
  2518.  
  2519.     /*
  2520.      * Allocate the bitmap.
  2521.      */
  2522.     bitmap = (unsigned char *)malloc(
  2523.     (unsigned) headerPtr->fdBitmapBlocks * FS_BLOCK_SIZE);
  2524.     if (Disk_BlockRead(fid, headerPtr, headerPtr->fdBitmapOffset,
  2525.           headerPtr->fdBitmapBlocks, (Address)bitmap) < 0) {
  2526.     fprintf(stderr, "ReadFileDescBitmap: Read failed");
  2527.     exit(1);
  2528.     }
  2529.     return(bitmap);
  2530. }
  2531.  
  2532. /*
  2533.  *----------------------------------------------------------------------
  2534.  *
  2535.  * ReadBitmap --
  2536.  *
  2537.  *    Read the bitmap off disk.
  2538.  *
  2539.  * Results:
  2540.  *    A pointer to the bitmap.
  2541.  *
  2542.  * Side effects:
  2543.  *    Memory allocated for the bit map.
  2544.  *
  2545.  *----------------------------------------------------------------------
  2546.  */
  2547. static unsigned char *
  2548. ReadBitmap(fid, headerPtr)
  2549.     int            fid;        /* Handle on raw disk. */
  2550.     Ofs_DomainHeader     *headerPtr;    /* Domain header. */
  2551. {
  2552.     unsigned char *bitmap;
  2553.  
  2554.     bitmap = (unsigned char *)malloc((unsigned) 
  2555.         headerPtr->bitmapBlocks * FS_BLOCK_SIZE);
  2556.     if (Disk_BlockRead(fid, headerPtr, headerPtr->bitmapOffset,
  2557.           headerPtr->bitmapBlocks, (Address) bitmap) < 0) {
  2558.     fprintf(stderr, "ReadBitmap: Read failed");
  2559.     exit(1);
  2560.     }
  2561.     return(bitmap);
  2562. }
  2563.  
  2564. /*
  2565.  *----------------------------------------------------------------------
  2566.  *
  2567.  * WriteFileDescBitmap --
  2568.  *
  2569.  *    Write out the file descriptor bitmap.
  2570.  *
  2571.  * Results:
  2572.  *    None.
  2573.  *
  2574.  * Side effects:
  2575.  *    None.
  2576.  *
  2577.  *----------------------------------------------------------------------
  2578.  */
  2579. static void
  2580. WriteFileDescBitmap(fid, headerPtr, bitmap)
  2581.     int            fid;        /* Handle on raw disk. */
  2582.     Ofs_DomainHeader     *headerPtr;    /* Domain header. */
  2583.     unsigned char     *bitmap;    /* Bitmap to write. */
  2584. {
  2585.     if (Disk_BlockWrite(fid, headerPtr, headerPtr->fdBitmapOffset,
  2586.            headerPtr->fdBitmapBlocks, (Address)bitmap) < 0) {
  2587.     fprintf(stderr, "WriteFileDescBitmap: Write failed");
  2588.     exit(1);
  2589.     }
  2590. }
  2591.  
  2592. @
  2593.  
  2594.  
  2595. 1.18
  2596. log
  2597. @lost+found has correct permissions, fixed bug in calculating number
  2598. of bitmap blocks, uses ofs.
  2599. @
  2600. text
  2601. @d11 1
  2602. a11 1
  2603. static char rcsid[] = "$Header: /sprite/src/admin/fsmake/RCS/fsmake.c,v 1.17 90/10/10 15:59:33 rab Exp $ SPRITE (Berkeley)";
  2604. d15 1
  2605. d1378 1
  2606. d1391 3
  2607. a1393 1
  2608.      * cylinder boundary after the start of the bitmap.
  2609. d1399 2
  2610. a1400 2
  2611.                       geoPtr->blocksPerCylinder -
  2612.                       headerPtr->dataOffset;
  2613. d1403 1
  2614. a1403 1
  2615.                     geoPtr->blocksPerCylinder); 
  2616. d1406 14
  2617. @
  2618.  
  2619.  
  2620. 1.17
  2621. log
  2622. @Made changes so that fsmake will compile and run under unix.
  2623. Added an option to allow alternative spritehosts file.
  2624. Added static declarations.
  2625. @
  2626. text
  2627. @d11 1
  2628. a11 1
  2629. static char rcsid[] = "$Header: /sprite/src/admin/fsmake/RCS/fsmake.c,v 1.16 90/09/12 08:47:49 jhh Exp Locker: rab $ SPRITE (Berkeley)";
  2630. d136 2
  2631. a137 2
  2632. static Fsdm_DomainHeader *headerPtr;    /* The domain header. */
  2633. static Fsdm_SummaryInfo *summaryPtr;    /* The summary info. */
  2634. d151 1
  2635. a151 1
  2636.     Fsdm_DomainHeader *headerPtr, int spriteID, int partition));
  2637. d153 1
  2638. a153 1
  2639.     Fsdm_Geometry *geoPtr));
  2640. d155 1
  2641. a155 1
  2642.     Fsdm_Geometry *geoPtr));
  2643. d157 3
  2644. a159 3
  2645.     Fsdm_DomainHeader *headerPtr));
  2646. static void SetSummaryInfo _ARGS_((Fsdm_DomainHeader *headerPtr,
  2647.     Fsdm_SummaryInfo *summaryPtr));
  2648. d161 2
  2649. a162 2
  2650.     Fsdm_DomainHeader *headerPtr));
  2651. static char *MakeFileDescBitmap _ARGS_((Fsdm_DomainHeader *headerPtr));
  2652. d164 1
  2653. a164 1
  2654.     Fsdm_DomainHeader *headerPtr));
  2655. d166 1
  2656. a166 1
  2657.     Fsdm_DomainHeader *headerPtr, Fsdm_FileDescriptor *fdPtr));
  2658. d168 1
  2659. a168 1
  2660.     Fsdm_DomainHeader *headerPtr));
  2661. d173 1
  2662. a173 1
  2663.     Fsdm_DomainHeader *headerPtr, Boolean writeDisk, DirIndexInfo *dirIndexPtr,
  2664. d175 1
  2665. a175 1
  2666. static ReturnStatus OpenDir _ARGS_((int fid, Fsdm_DomainHeader *headerPtr,
  2667. d178 1
  2668. a178 1
  2669. static ReturnStatus NextDirEntry _ARGS_((int fid, Fsdm_DomainHeader *headerPtr,
  2670. d181 1
  2671. a181 1
  2672. static ReturnStatus CloseDir _ARGS_((int fid, Fsdm_DomainHeader *headerPtr,
  2673. d183 1
  2674. a183 1
  2675. static ReturnStatus ReadFileDesc _ARGS_((int fid, Fsdm_DomainHeader *headerPtr,
  2676. d185 1
  2677. a185 1
  2678. static ReturnStatus WriteFileDesc _ARGS_((int fid, Fsdm_DomainHeader *headerPtr,
  2679. d189 1
  2680. a189 1
  2681. static void MarkDataBitmap _ARGS_((Fsdm_DomainHeader *headerPtr,
  2682. d192 1
  2683. a192 1
  2684.     Fsdm_DomainHeader *headerPtr));
  2685. d194 2
  2686. a195 2
  2687.     Fsdm_DomainHeader *headerPtr));
  2688. static void WriteFileDescBitmap _ARGS_((int fid, Fsdm_DomainHeader *headerPtr,
  2689. d525 2
  2690. a526 2
  2691.     Fsdm_DomainHeader    oldDomainHeader;
  2692.     Fsdm_SummaryInfo    oldSummaryInfo;
  2693. d582 1
  2694. a582 1
  2695.     headerPtr = (Fsdm_DomainHeader *) malloc(sizeof(Fsdm_DomainHeader));
  2696. d601 1
  2697. a601 1
  2698.     summaryPtr = (Fsdm_SummaryInfo *) malloc(DEV_BYTES_PER_SECTOR);
  2699. d603 7
  2700. d1011 1
  2701. a1011 1
  2702.     Fsdm_DomainHeader     *headerPtr;    /* Domain header to fill in */
  2703. d1015 1
  2704. a1015 1
  2705.     register Fsdm_Geometry *geoPtr;/* The layout information for the disk */
  2706. d1017 1
  2707. a1017 1
  2708.     headerPtr->magic = FSDM_DOMAIN_MAGIC;
  2709. d1071 1
  2710. a1071 1
  2711.     register Fsdm_Geometry     *geoPtr;    /* Fancy geometry information */
  2712. d1087 1
  2713. a1087 1
  2714.     geoPtr->rotSetsPerCyl = FSDM_SCSI_MAPPING;
  2715. d1094 1
  2716. a1094 1
  2717.     for (index = 0 ; index < FSDM_MAX_ROT_POSITIONS ; index++) {
  2718. d1123 1
  2719. a1123 1
  2720.     register Fsdm_Geometry     *geoPtr;    /* Fancy geometry information */
  2721. d1256 1
  2722. a1256 1
  2723.         for (index = numBlocks; index < FSDM_MAX_ROT_POSITIONS; index++){
  2724. d1281 1
  2725. a1281 1
  2726.     for (index = 0 ; index < FSDM_MAX_ROT_POSITIONS ; index++) {
  2727. d1311 1
  2728. a1311 1
  2729.     register Fsdm_DomainHeader *headerPtr;
  2730. d1313 1
  2731. a1313 1
  2732.     register Fsdm_Geometry *geoPtr;
  2733. d1324 1
  2734. d1397 4
  2735. a1400 2
  2736.     bitmapBytes          = (headerPtr->dataBlocks * DISK_KBYTES_PER_BLOCK -
  2737.                        1) / BITS_PER_BYTE + 1;
  2738. d1452 2
  2739. a1453 2
  2740.     Fsdm_DomainHeader *headerPtr;    /* Domain header to summarize */
  2741.     Fsdm_SummaryInfo *summaryPtr;    /* Summary info to fill in */
  2742. d1456 1
  2743. a1456 1
  2744.     bzero((Address)summaryPtr, sizeof(Fsdm_SummaryInfo));
  2745. d1509 1
  2746. a1509 1
  2747.     register Fsdm_DomainHeader *headerPtr;
  2748. d1553 2
  2749. a1554 2
  2750.             0, 0755, curTime.tv_sec);
  2751.         for (j = 0; j < FSDM_NUM_LOST_FOUND_BLOCKS ; j++) {
  2752. d1563 1
  2753. a1563 1
  2754.             * (j + 1 + FSDM_NUM_LOST_FOUND_BLOCKS);
  2755. d1627 1
  2756. a1627 1
  2757.     register Fsdm_DomainHeader *headerPtr;
  2758. d1699 1
  2759. a1699 1
  2760.     register Fsdm_DomainHeader *headerPtr;
  2761. d1747 1
  2762. a1747 1
  2763.     register Fsdm_DomainHeader     *headerPtr;    /* Domain header. */
  2764. d1815 1
  2765. a1815 1
  2766.     register Fsdm_DomainHeader *headerPtr;
  2767. d1818 1
  2768. a1818 1
  2769.     char         block[FSDM_NUM_LOST_FOUND_BLOCKS * FS_BLOCK_SIZE];
  2770. d1822 1
  2771. a1822 1
  2772.     CreateDir(block, FSDM_NUM_LOST_FOUND_BLOCKS, FSDM_LOST_FOUND_FILE_NUMBER, 
  2773. d1835 1
  2774. a1835 1
  2775.             FSDM_NUM_LOST_FOUND_BLOCKS, block);
  2776. d1944 1
  2777. a1944 1
  2778.     Fsdm_DomainHeader     *headerPtr;    /* Domain header. */
  2779. d2033 1
  2780. a2033 1
  2781.     Fsdm_DomainHeader     *headerPtr;    /* Domain header. */
  2782. d2100 1
  2783. a2100 1
  2784.     Fsdm_DomainHeader     *headerPtr;    /* Domain header. */
  2785. d2175 1
  2786. a2175 1
  2787.     Fsdm_DomainHeader     *headerPtr;    /* Domain header. */
  2788. d2209 1
  2789. a2209 1
  2790.     Fsdm_DomainHeader     *headerPtr;    /* Domain header. */
  2791. d2247 1
  2792. a2247 1
  2793.     Fsdm_DomainHeader     *headerPtr;    /* Domain header. */
  2794. d2345 1
  2795. a2345 1
  2796.     Fsdm_DomainHeader    *headerPtr;
  2797. d2378 1
  2798. a2378 1
  2799.     Fsdm_DomainHeader     *headerPtr;    /* Domain header. */
  2800. d2413 1
  2801. a2413 1
  2802.     Fsdm_DomainHeader     *headerPtr;    /* Domain header. */
  2803. d2445 1
  2804. a2445 1
  2805.     Fsdm_DomainHeader     *headerPtr;    /* Domain header. */
  2806. @
  2807.  
  2808.  
  2809. 1.16
  2810. log
  2811. @Lots and lots of changes.
  2812. @
  2813. text
  2814. @d11 2
  2815. a12 2
  2816. static char rcsid[] = "$Header: /sprite/src/admin/fsmake/RCS/fsmake.c,v 1.14.1.1 90/07/02 22:15:18 jhh Exp $ SPRITE (Berkeley)";
  2817. #endif not lint
  2818. d19 1
  2819. a19 1
  2820. int kbytesToFileDesc = 4;    /* The ratio of kbytes to
  2821. d21 1
  2822. a21 1
  2823. Boolean printOnly = TRUE;    /* Stop after computing the domain header
  2824. d23 2
  2825. a24 1
  2826. Boolean overlapBlocks = FALSE;    /* Allow filesystem blocks to overlap track
  2827. d26 1
  2828. a26 1
  2829. Boolean scsiDisk = TRUE;    /* If TRUE then simpler geometry is computed
  2830. d32 2
  2831. a33 2
  2832. int    bootSectors = -1;    /* Number of boot sectors. */
  2833. int    hostID    = 0;        /* Host id to write into domain header. 
  2834. d35 3
  2835. a37 2
  2836. Boolean repartition = FALSE;    /* If TRUE then the partition map is changed. */
  2837. Boolean reconfig = FALSE;    /* If TRUE then the disk configuration
  2838. d39 2
  2839. a40 1
  2840. Boolean partdisktab = FALSE;    /* If TRUE then read the partition map from
  2841. d42 2
  2842. a43 1
  2843. Boolean configdisktab = FALSE;    /* If TRUE then read the config information
  2844. d47 5
  2845. a51 5
  2846. char *disktabName = "/etc/disktab"; /* Name of disktab file. */
  2847. char *sizeString = NULL;    /* Size of partitions. */
  2848. char *diskType = NULL;        /* Type of disk (e.g.rz55). */
  2849. char *labelTypeName = NULL;    /* Type of label (e.g. sun). */
  2850. char *dirName = NULL;        /* Name of directory that contains files to
  2851. d53 3
  2852. d63 7
  2853. a69 7
  2854. char *deviceName;        /* Set to "rsd0" or "rxy1", etc. */
  2855. char *partName;            /* Set to "a", "b", "c" ... "g" */
  2856. char *rawDeviceName;        /* Set to "raw_rsd00", etc */
  2857. char defaultFirstPartName[] = "a";
  2858. char *firstPartName = defaultFirstPartName;
  2859. char defaultDevDirectory[] = "/dev";
  2860. char *devDirectory = defaultDevDirectory;
  2861. d71 1
  2862. a71 1
  2863. char *hostIDString = NULL;
  2864. d73 1
  2865. a73 1
  2866. Option optionArray[] = {
  2867. d118 2
  2868. a119 1
  2869.  
  2870. d121 1
  2871. a121 1
  2872. int numOptions = sizeof(optionArray) / sizeof(Option);
  2873. d127 1
  2874. a127 1
  2875. struct timeval curTime;
  2876. d129 3
  2877. a131 3
  2878. int            freeFDNum;    /* The currently free file descriptor.*/
  2879. int            freeBlockNum;    /* The currently free data block. */
  2880. unsigned char        *fdBitmapPtr;    /* Pointer to the file descriptor
  2881. d133 2
  2882. a134 2
  2883. unsigned char        *cylBitmapPtr;    /* Pointer to the cylinder bit map. */
  2884. int            bytesPerCylinder;/* The number of bytes in
  2885. d136 2
  2886. a137 2
  2887. Fsdm_DomainHeader     *headerPtr;    /* The domain header. */
  2888. Fsdm_SummaryInfo     *summaryPtr;    /* The summary info. */
  2889. d139 1
  2890. a139 1
  2891. char *myName;
  2892. d143 54
  2893. a196 15
  2894. void SetSummaryInfo();
  2895. ReturnStatus SetDomainHeader();
  2896. void SetDiskGeometry();
  2897. void SetSCSIDiskGeometry();
  2898. void SetDomainParts();
  2899. void SetRootFileDescriptor();
  2900. void SetBadBlockFileDescriptor();
  2901. void SetLostFoundFileDescriptor();
  2902. void SetEmptyFileDescriptor();
  2903. void SetFscheckOutFileDescriptor();
  2904. ReturnStatus WriteFileDesc();
  2905. void WriteFileDescBitmap();
  2906. ReturnStatus WriteBitmap();
  2907. char *MakeFileDescBitmap();
  2908. void Usage();
  2909. d219 1
  2910. d304 1
  2911. d426 1
  2912. d428 1
  2913. a428 1
  2914.     
  2915. d441 3
  2916. a443 1
  2917.     } else {
  2918. d493 1
  2919. a493 1
  2920. void
  2921. d515 1
  2922. a515 1
  2923. ReturnStatus
  2924. d645 1
  2925. a645 1
  2926. void
  2927. d656 1
  2928. a656 1
  2929.     Fslcl_DirEntry    *unixDirEntPtr;
  2930. a674 1
  2931.     
  2932. d676 1
  2933. d721 3
  2934. a723 6
  2935.     for (unixDirEntPtr = (Fslcl_DirEntry *)readdir(unixDirPtr);
  2936.        unixDirEntPtr != NULL;
  2937.        unixDirEntPtr = (Fslcl_DirEntry *)readdir(unixDirPtr)) {
  2938.  
  2939.     if (unixDirEntPtr->nameLength == 1 && 
  2940.         strncmp(unixDirEntPtr->fileName, ".", 1) == 0) {
  2941. d726 2
  2942. a727 2
  2943.     if (unixDirEntPtr->nameLength == 2 && 
  2944.         strncmp(unixDirEntPtr->fileName, "..", 2) == 0) {
  2945. d730 2
  2946. a731 2
  2947.     strncpy(fileName, unixDirEntPtr->fileName, unixDirEntPtr->nameLength);
  2948.     fileName[unixDirEntPtr->nameLength] = 0;
  2949. d810 1
  2950. a810 1
  2951.         int    fd;
  2952. d1001 1
  2953. a1001 1
  2954. ReturnStatus
  2955. d1061 1
  2956. a1061 1
  2957. void
  2958. d1113 1
  2959. a1113 1
  2960. void
  2961. d1120 1
  2962. a1120 1
  2963.     int tracksPerSet;        /* Total number of tracks in a rotational set */
  2964. d1125 1
  2965. a1125 1
  2966.     int offsetIncrement;    /* The skew of the starting offset on each
  2967. d1127 1
  2968. a1127 1
  2969.     Boolean overlap;        /* TRUE if filesystem blocks overlap tracks */
  2970. d1300 1
  2971. a1300 1
  2972. void
  2973. d1440 1
  2974. a1440 1
  2975. void
  2976. d1496 1
  2977. a1496 1
  2978. ReturnStatus
  2979. d1615 1
  2980. a1615 1
  2981. char *
  2982. d1686 1
  2983. a1686 1
  2984. ReturnStatus
  2985. d1734 1
  2986. a1734 1
  2987. ReturnStatus
  2988. d1802 1
  2989. a1802 1
  2990. ReturnStatus
  2991. d1849 1
  2992. a1849 1
  2993. void
  2994. d1930 1
  2995. a1930 1
  2996. ReturnStatus
  2997. d2020 1
  2998. a2020 1
  2999. ReturnStatus
  3000. d2087 1
  3001. a2087 1
  3002. ReturnStatus
  3003. d2162 1
  3004. a2162 1
  3005. ReturnStatus
  3006. d2196 1
  3007. a2196 1
  3008. ReturnStatus
  3009. d2234 1
  3010. a2234 1
  3011. ReturnStatus
  3012. d2275 1
  3013. a2275 1
  3014. void
  3015. d2333 1
  3016. a2333 1
  3017. void
  3018. d2365 1
  3019. a2365 1
  3020. unsigned char *
  3021. d2400 1
  3022. a2400 1
  3023. unsigned char *
  3024. d2432 1
  3025. a2432 1
  3026. void
  3027. @
  3028.  
  3029.  
  3030. 1.15
  3031. log
  3032. @started interactive stuff
  3033. @
  3034. text
  3035. @d11 1
  3036. a11 1
  3037. static char rcsid[] = "$Header: /user1/jhh/src/cmds/fsmake/RCS/fsmake.c,v 1.14 89/10/03 13:13:03 jhh Exp Locker: jhh $ SPRITE (Berkeley)";
  3038. d14 1
  3039. a14 21
  3040. #include "sprite.h"
  3041. #include "option.h"
  3042. #include "diskUtils.h"
  3043. #include <stdio.h>
  3044. #include <sys/file.h>
  3045. #include <stdlib.h>
  3046. #include <string.h>
  3047. #include <host.h>
  3048. #include <sys/time.h>
  3049. #include <assert.h>
  3050.  
  3051. /*
  3052.  * Some number of sectors in the root partition must be allocated to the
  3053.  * boot program. The default is for the new filesystem to have the same
  3054.  * number of boot sectors as the old filesystem. If the disk did not
  3055.  * previously have a filesystem, or if the domain header cannot be found,
  3056.  * then the following number of boot sectors are allocated. The standard
  3057.  * Sun format is for the summary sector to be in sector #17. 16 boot sectors
  3058.  * and one disk label fill the first 17 sectors.
  3059.  */
  3060. int    defaultBootSectors = 16;
  3061. a22 2
  3062. Boolean makeFile = FALSE;    /* Make a file in the root directory,
  3063.                  * this is used when testing the filesystem */
  3064. d34 16
  3065. d58 1
  3066. d71 2
  3067. a76 2
  3068.     {OPT_TRUE, "file", (Address)&makeFile,
  3069.     "Make a file in the root directory (FALSE)"},
  3070. d85 2
  3071. a86 2
  3072.     {OPT_STRING, "dir", (Address)&devDirectory,
  3073.     "Name of device directory (\"/dev/\")"},
  3074. d93 19
  3075. a115 7
  3076.  * Information for setting up the .fscheck.out file.
  3077.  */
  3078.  
  3079. Boolean makeFscheckOut = FALSE;
  3080. char *fscheckOutName = ".fscheck.out";
  3081.  
  3082. /*
  3083. d119 1
  3084. a119 1
  3085. struct timeval currentTime;
  3086. d121 9
  3087. a129 5
  3088. #ifdef sprite
  3089. Boolean sprite = TRUE;
  3090. #else
  3091. Boolean sprite = FALSE;
  3092. #endif
  3093. d131 1
  3094. d136 1
  3095. a136 1
  3096. void SetDomainHeader();
  3097. d146 1
  3098. a146 1
  3099. ReturnStatus WriteFileDescBitmap();
  3100. d149 3
  3101. d179 1
  3102. d186 4
  3103. a189 4
  3104.     Boolean interactive;
  3105.     char    *partitions;
  3106.     char    *answer;
  3107.     char    buffer[100];
  3108. d191 4
  3109. a194 203
  3110.     gettimeofday(¤tTime, NULL);
  3111.     if (argc == 1) {
  3112.     interactive = TRUE;
  3113.     deviceName = NULL;
  3114.     partitions = NULL;
  3115.     printf("Please answer the following questions.\n");
  3116.     printf("Options are in square brackets []\n");
  3117.     printf("Default answers are in parenthesis ()\n");
  3118.     printf("\n");
  3119. startQuestions:
  3120.     (void) Prompt("Name of the device directory", NULL, NULL, FALSE, TRUE,
  3121.         &devDirectory);
  3122.     while(! Prompt("Device", NULL, "raw_rsd00", TRUE, TRUE, &deviceName)) {
  3123.         printf("You must specify a device name\n");
  3124.     }
  3125.     while(1) {
  3126.         Boolean done = FALSE;
  3127.         int choice;
  3128.         answer = buffer;
  3129.         *answer = '1';
  3130. labelA:
  3131.         (void) Prompt(
  3132. "Do you want to:\n\t1) Put one filesystem on partition c\n\t2) Put a filesystem on both partitions a and g\n\t3) Specify the partitions yourself?", 
  3133.         "1,2,3", NULL, FALSE, FALSE, &answer));
  3134.         n = sscanf(answer, "%d", choice);
  3135.         if (n == 0 || choice < 1 || choice > 3) {
  3136.         printf("Please answer with 1,2, or 3\n");
  3137.         goto labelA;
  3138.         }
  3139.         switch (choice) {
  3140.         case 1 : {
  3141.             partitions = malloc(2);
  3142.             strcpy(partitions, "c");
  3143.             numPartitons = 1;
  3144.             done = TRUE;
  3145.             break;
  3146.         }
  3147.         case 2 : {
  3148.             partitions = malloc(3);
  3149.             strcpy(partitions, "ag");
  3150.             numPartitions = 2;
  3151.             done = TRUE;
  3152.             break;
  3153.         }
  3154.         case 3 : {
  3155.             while(1) {
  3156.             while(! Prompt("Partitions", "a,b,c,d,e,f,g", "ag", 
  3157.                 TRUE, TRUE, &partitions)) {
  3158.                 printf("You must specify at least one partition\n");
  3159.             }
  3160.             if (strspn(partitions, "abcdefg") == 
  3161.                 strlen(partitions)) {
  3162.                 numPartitions = strlen(partitions);
  3163.                 done = TRUE;
  3164.                 break;
  3165.             }
  3166.             printf("A partition letter is one of a,b,c,d,e,f,g\n");
  3167.             *partitions = '\0';
  3168.             }
  3169.             break;
  3170.         }
  3171.         default: {
  3172.             printf("You must answer 1,2, or 3\n");
  3173.         }
  3174.         }
  3175.         if (done) {
  3176.         break;
  3177.         }
  3178.     }
  3179. #if 0
  3180.     for (i = 0; i < numPartitions; i++) {
  3181.         int        fd;
  3182.         char    buffer[100];
  3183.         sprintf(buffer, "%s/%s%c", devDirectory, deviceName, partitions[i]);
  3184.         fd = open(buffer,printOnly ? O_RDONLY : O_RDWR);
  3185.         if (fid < 0) {
  3186.         perror("Can't open %s\n", buffer);
  3187.         goto startQuestions;
  3188.         }
  3189.         close(fd);
  3190.     }
  3191. #endif
  3192.     answer = buffer;
  3193.     *answer = 'n';
  3194.     (void) Prompt(
  3195.     "Do any of the disk partitions contain filesystems that you wish to keep?",
  3196.         "y/n", NULL, FALSE, FALSE, &answer);
  3197.     if (strcmp(answer, "n")) {
  3198.         okToChangeLabel = FALSE;
  3199.     }
  3200.     answer = buffer;
  3201.     *answer = 'y';
  3202.     (void) Prompt("Is this a scsi disk?", "y/n", NULL, FALSE, FALSE, 
  3203.         &answer);
  3204.     if (!strcmp(answer, "n")) {
  3205.         scsiDisk = FALSE;
  3206.     }
  3207.     sprintf(buffer, "%s/%sa", devDirectory, deviceName);
  3208.     fd = open(buffer, printOnly ? O_RDONLY : O_RDWR);
  3209.     diskInfoPtr = Disk_ReadDiskInfo(fd, 'a');
  3210.     if (diskInfoPtr == NULL) {
  3211.         answer = buffer;
  3212.         *answer = '1';
  3213.         printf("The disk does not appear to have a label.\n");
  3214.         printf("I'll have to write one on it.\n");
  3215.         printf("Please enter the disk type (one word) as it appears\n");
  3216.         printf("in /etc/disktab.\n");
  3217.         if (sprite && scsiDisk) {
  3218.         char *diskType = NULL;
  3219.  
  3220.         (void) Prompt(NULL, NULL, "rz55", TRUE, TRUE, &diskType); 
  3221. labelB:
  3222.         printf("You have a choice.\n");
  3223.         printf("I can either create a label from /etc/disktab,\n");
  3224.         printf("or I can make one up to maximize disk usage.\n"
  3225.         printf("The made up label will contain incorrect values\n");
  3226.         printf("for the number of heads, sector/track, etc,\n");
  3227.         printf("but it will give you more disk and probably won't\n");
  3228.         printf("affect the performance.\n");
  3229.         (void) Prompt(
  3230.     "Which to you prefer? 1) make up a good label. 2) use /etc/disktab\n",
  3231.                 "1,2", NULL, FALSE, FALSE, &answer);
  3232.         n = sscanf(answer, "%d", choice);
  3233.         if (n == 0 || choice < 1 || choice > 2) {
  3234.             printf("Please answer with 1 or 2\n");
  3235.             goto labelB;
  3236.         if (choice == 1) {
  3237.             diskInfoPtr = FindBestLayout(diskType, NULL);
  3238.         } else {
  3239.             diskInfoPtr = ScanDiskTab(diskType, NULL);
  3240.         }
  3241.         } else {
  3242.         diskInfoPtr = ScanDiskTab(diskType, NULL);
  3243.         }
  3244.     } else if (sprite && okToChangeLabel) {
  3245.         printf("I may be able to modify the disk label to allow\n");
  3246.         printf("better utilization of the disk.\n");
  3247.         answer = buffer;
  3248.         *answer = 'y';
  3249.         (void) Prompt("Do you want me to do this?", "y/n", NULL, 
  3250.         FALSE, FALSE, &answer);
  3251.         if (!strcmp(answer, 'y')) {
  3252.             char *diskType = NULL;
  3253.         (void) Prompt(
  3254.             "Please enter a one-word name for the disk type",
  3255.             NULL, "wrenIV", TRUE, TRUE, &diskType); 
  3256.         diskInfoPtr = FindBestLayout(diskType, diskInfoPtr);
  3257.         }
  3258.     }
  3259.     if (okToChangeLabel) {
  3260.         char    question[100];
  3261.         int        free = 100;
  3262. labelC;
  3263.         answer = buffer;
  3264.         sprintf(answer, "%d", free);
  3265.         for (i = 0; i < numPartitions; i++) {
  3266.         sprintf(question, 
  3267.     "What percentage of the disk should partition %c represent (approx)",
  3268.             partitions[i]);
  3269.         while(1) {
  3270.             (void) Prompt(question, NULL, NULL, FALSE, FALSE, &answer);
  3271.             n = sscanf(answer, "%d", amount);
  3272.             if (n != 0 && amount >= 0 && amount <= free) {
  3273.             break;
  3274.             }
  3275.             if (amount > free) {
  3276.             printf("There is only %d percent free on the disk\n",
  3277.                 free);
  3278.             }
  3279.         }
  3280.         partitionInfo[i].name = partitions[i];
  3281.         partitionInfo[i].pct = amount;
  3282.         free -= amount;
  3283.         }
  3284.         for (i = 0; i < numPartitions; i++) {
  3285.         printf("Partition: %c, pct: %d\n", partitionInfo[i].name,
  3286.             partitionInfo[i].pct);
  3287.         }
  3288.         answer = buffer;
  3289.         strcpy(answer, "y");
  3290.         (void) Prompt("These look ok?", "y/n", NULL, FALSE, FALSE,
  3291.         &answer);
  3292.         if (!strcmp(answer, "n")) {
  3293.         goto labelC;
  3294.         }
  3295.     }
  3296.  
  3297.  
  3298.  
  3299.  
  3300.  
  3301.  
  3302.     } else {
  3303.     interactive = FALSE;
  3304.     (void)Opt_Parse(argc, argv,optionArray, numOptions, 0);
  3305.     if (deviceName == (char *)0) {
  3306.         fprintf(stderr,"Specify device name with -dev option\n");
  3307.         status = FAILURE;
  3308.     }
  3309.     if (partName == (char *)0) {
  3310.         fprintf(stderr,"Specify partition with -part option\n");
  3311.         status = FAILURE;
  3312.     }
  3313. a195 1
  3314.  
  3315. d197 8
  3316. d215 37
  3317. d255 1
  3318. a255 1
  3319.     Host_Entry    *entry;
  3320. d258 6
  3321. a263 1
  3322.         entry = Host_ByID(temp);
  3323. d265 18
  3324. a282 4
  3325.         entry = Host_ByName(hostIDString);
  3326.     }
  3327.     if (entry == NULL) {
  3328.         fprintf(stderr, "No such host \"%s\"\n", hostIDString);
  3329. a283 2
  3330.     } else {
  3331.         hostID = entry->id;
  3332. a285 1
  3333.  
  3334. d293 23
  3335. a315 9
  3336.     (void) strcpy(firstPartitionName, devDirectory);    /* eg. /dev/ */
  3337.     (void) strcpy(partitionName, devDirectory);
  3338.     (void) strcat(firstPartitionName, deviceName);    /* eg. /dev/rxy0 */
  3339.     (void) strcat(partitionName, deviceName);
  3340.     (void) strcat(firstPartitionName, firstPartName);    /* eg. /dev/rxy0a */
  3341.     (void) strcat(partitionName, partName);        /* eg. /dev/rxy0b */
  3342.  
  3343.  
  3344.     firstPartFID = open(firstPartitionName, O_RDONLY);
  3345. d317 2
  3346. a318 1
  3347.     perror("Can't open first partition");
  3348. d337 39
  3349. a375 9
  3350.     /*
  3351.      * Put a .fscheck.out file in all 'a' and 'c' partitions. We really only
  3352.      * need one in the root partition for the fileserver, but it is more 
  3353.      * convienient to just put one in all potential root partitions than 
  3354.      * it is to add a new option and have the users remember to use it.
  3355.      *
  3356.      */
  3357.     if ((partition == 0) || (partition == 2)) {
  3358.     makeFscheckOut = TRUE;
  3359. d395 1
  3360. d397 21
  3361. a417 2
  3362.     status = MakeFilesystem(firstPartFID, partFID, partition, spriteID);
  3363.  
  3364. d428 23
  3365. d464 1
  3366. a464 1
  3367. MakeFilesystem(firstPartFID, partFID, partition, spriteID)
  3368. d470 1
  3369. d473 11
  3370. a483 23
  3371.     Disk_Info         *diskInfoPtr;
  3372.     Fsdm_DomainHeader     *headerPtr;
  3373.     Fsdm_SummaryInfo     *summaryPtr;
  3374.     Fsdm_SummaryInfo     *oldSummaryPtr;
  3375.     char         answer[10];
  3376.     char         block[DEV_BYTES_PER_SECTOR];
  3377.     int            i;
  3378.  
  3379.     /*
  3380.      * Read the copy of the super block at the beginning of the partition
  3381.      * to find out basic disk geometry and where to write the domain header.
  3382.      */
  3383.     diskInfoPtr = Disk_ReadDiskInfo(firstPartFID, partition);
  3384.     if (diskInfoPtr == (Disk_Info *)0) {
  3385.     fprintf(stderr,"MakeFilesystem: Unable to read super block.\n");
  3386.     return(FAILURE);
  3387.     }
  3388.     if (diskInfoPtr->summarySector > 0) {
  3389.  
  3390.     status = Disk_SectorRead(partFID, diskInfoPtr->summarySector, 1, block);
  3391.     if (status != SUCCESS) {
  3392.         perror("Summary sector read failed");
  3393.         return status;
  3394. d485 4
  3395. a488 1
  3396.     oldSummaryPtr = (Fsdm_SummaryInfo *) block;
  3397. d490 2
  3398. d493 1
  3399. a493 1
  3400.         oldSummaryPtr->domainPrefix);
  3401. d499 1
  3402. a499 1
  3403.         exit(SUCCESS);
  3404. d503 4
  3405. a506 7
  3406.     bzero(block, DEV_BYTES_PER_SECTOR);
  3407.     /*
  3408.      * Clear out the old summary sector and domain header. This is especially
  3409.      * important if we are going to move them.
  3410.      */
  3411.     if ((!printOnly) && (diskInfoPtr->summarySector != -1)) {
  3412.     status = Disk_SectorWrite(partFID, diskInfoPtr->summarySector,1, block);
  3413. d508 1
  3414. a508 2
  3415.         perror("Clear of old summary sector failed"); 
  3416.         return(status);
  3417. d510 3
  3418. a512 7
  3419.     for (i = 0; i < diskInfoPtr->numDomainSectors; i++) {
  3420.         status = Disk_SectorWrite(partFID, diskInfoPtr->domainSector+i,
  3421.                 1, block);
  3422.         if (status != SUCCESS) {
  3423.         perror("Clear of old domain header failed"); 
  3424.         return(status);
  3425.         }
  3426. d519 15
  3427. a533 2
  3428.     diskInfoPtr->summarySector = bootSectors + 1;
  3429.     diskInfoPtr->domainSector = bootSectors + 2;
  3430. a534 11
  3431.     /* 
  3432.      * The user has not specified the number of boot sectors, and the disk
  3433.      * did not previously have a filesystem on it.
  3434.      */
  3435.     if (diskInfoPtr->summarySector == -1) {
  3436.     diskInfoPtr->summarySector = defaultBootSectors + 1;
  3437.     diskInfoPtr->domainSector = defaultBootSectors + 2;
  3438.     }
  3439.     headerPtr = (Fsdm_DomainHeader *)
  3440.     malloc((unsigned) diskInfoPtr->numDomainSectors * DEV_BYTES_PER_SECTOR);
  3441.     SetDomainHeader(diskInfoPtr, headerPtr, spriteID, partition);
  3442. d538 4
  3443. a541 6
  3444.     if (partition != 0) {
  3445.         status = CopySuperBlock(firstPartFID, partFID);
  3446.         if (status != SUCCESS) {
  3447.         perror("CopySuperBlock failed"); 
  3448.         return(status);
  3449.         }
  3450. d543 1
  3451. a543 2
  3452.     status = Disk_SectorWrite(partFID, diskInfoPtr->domainSector,
  3453.                 diskInfoPtr->numDomainSectors, (Address)headerPtr);
  3454. d550 2
  3455. a551 12
  3456.     SetSummaryInfo(diskInfoPtr, headerPtr, summaryPtr);
  3457.     Disk_PrintSummaryInfo(summaryPtr);
  3458.     if (!printOnly) {
  3459.     status = Disk_SectorWrite(partFID, diskInfoPtr->summarySector, 1,
  3460.                 (Address)summaryPtr);
  3461.     if (status != SUCCESS) {
  3462.         perror("Summary sector  write failed");
  3463.         return(status);
  3464.     }
  3465.     }
  3466.  
  3467.     status = WriteFileDesc(headerPtr, partFID);
  3468. d553 1
  3469. a553 1
  3470.     perror("WriteFileDesc failed");
  3471. d556 1
  3472. a556 1
  3473.     status = WriteBitmap(headerPtr, partFID);
  3474. d561 3
  3475. a563 1
  3476.     status = WriteRootDirectory(headerPtr, partFID);
  3477. d568 1
  3478. a568 1
  3479.     status = WriteLostFoundDirectory(headerPtr, partFID);
  3480. d579 1
  3481. a579 1
  3482.  * CopySuperBlock --
  3483. d581 2
  3484. a582 2
  3485.  *    Copy the super block from the first sector of the disk to
  3486.  *    the first sector of the partition being formatted.
  3487. d584 307
  3488. a890 15
  3489.  * Results:
  3490.  *    A return code from the I/O.
  3491.  *
  3492.  * Side effects:
  3493.  *    Writes on the zero'th sector of the partition.
  3494.  *
  3495.  *----------------------------------------------------------------------
  3496.  */
  3497. ReturnStatus
  3498. CopySuperBlock(firstPartFID, partFID)
  3499.     int firstPartFID;
  3500.     int partFID;
  3501. {
  3502.     ReturnStatus status;
  3503.     char *block;
  3504. d892 42
  3505. a933 1
  3506.     block = (char *)malloc(DEV_BYTES_PER_SECTOR);
  3507. a934 7
  3508.     status = Disk_SectorRead(firstPartFID, 0, 1, block);
  3509.     if (status != SUCCESS) {
  3510.     return(status);
  3511.     }
  3512.     status = Disk_SectorWrite(partFID, 0, 1, block);
  3513.     return(status);
  3514. }
  3515. d952 6
  3516. a957 6
  3517. void
  3518. SetDomainHeader(diskInfoPtr, headerPtr, spriteID, partition)
  3519.     Disk_Info *diskInfoPtr;    /* Information from the super block */
  3520.     Fsdm_DomainHeader *headerPtr;    /* Reference to domain header to fill in */
  3521.     int spriteID;        /* Host ID of machine with the disks */
  3522.     int partition;        /* Index of partition to format */
  3523. d962 7
  3524. a968 2
  3525.     headerPtr->firstCylinder = diskInfoPtr->firstCylinder;
  3526.     headerPtr->numCylinders = diskInfoPtr->numCylinders;
  3527. d985 1
  3528. a985 1
  3529.     SetSCSIDiskGeometry(diskInfoPtr, geoPtr);
  3530. d987 1
  3531. a987 1
  3532.     SetDiskGeometry(diskInfoPtr, geoPtr);
  3533. d990 2
  3534. a991 1
  3535.     SetDomainParts(diskInfoPtr, headerPtr);
  3536. d1013 3
  3537. a1015 3
  3538. SetSCSIDiskGeometry(diskInfoPtr, geoPtr)
  3539.     register Disk_Info *diskInfoPtr;/* Basic geometry information */
  3540.     register Fsdm_Geometry *geoPtr;    /* Fancy geometry information */
  3541. d1020 2
  3542. a1021 2
  3543.     geoPtr->numHeads = diskInfoPtr->numHeads;
  3544.     geoPtr->sectorsPerTrack = diskInfoPtr->numSectors;
  3545. d1065 3
  3546. a1067 3
  3547. SetDiskGeometry(diskInfoPtr, geoPtr)
  3548.     register Disk_Info *diskInfoPtr;/* Basic geometry information */
  3549.     register Fsdm_Geometry *geoPtr;    /* Fancy geometry information */
  3550. d1080 2
  3551. a1081 2
  3552.     geoPtr->numHeads = diskInfoPtr->numHeads;
  3553.     geoPtr->sectorsPerTrack = diskInfoPtr->numSectors;
  3554. d1252 3
  3555. a1254 2
  3556. SetDomainParts(diskInfoPtr, headerPtr)
  3557.     register Disk_Info *diskInfoPtr;
  3558. d1266 2
  3559. d1274 7
  3560. d1286 2
  3561. a1287 5
  3562.     cylinders = (diskInfoPtr->domainSector + 
  3563.             diskInfoPtr->numDomainSectors) /
  3564.             (geoPtr->sectorsPerTrack * geoPtr->numHeads);
  3565.     if (((diskInfoPtr->domainSector + diskInfoPtr->numDomainSectors) %
  3566.         (geoPtr->sectorsPerTrack * geoPtr->numHeads)) != 0) {
  3567. d1291 1
  3568. a1291 2
  3569.     numBlocks = geoPtr->blocksPerCylinder * diskInfoPtr->numCylinders -
  3570.             reservedBlocks;
  3571. d1297 3
  3572. a1299 5
  3573.     sets = (diskInfoPtr->domainSector + 
  3574.          diskInfoPtr->numDomainSectors) /
  3575.          (geoPtr->tracksPerRotSet * geoPtr->sectorsPerTrack);
  3576.     if (((diskInfoPtr->domainSector + diskInfoPtr->numDomainSectors) %
  3577.         (geoPtr->tracksPerRotSet * geoPtr->sectorsPerTrack)) != 0) {
  3578. d1303 1
  3579. a1303 2
  3580.     numBlocks = geoPtr->blocksPerCylinder * diskInfoPtr->numCylinders -
  3581.             reservedBlocks;
  3582. d1381 1
  3583. a1381 2
  3584.  *    Initialize the summary information for the domain.  It is well
  3585.  *    known that this occupies one sector.
  3586. d1392 1
  3587. a1392 2
  3588. SetSummaryInfo(diskInfoPtr, headerPtr, summaryPtr)
  3589.     Disk_Info *diskInfoPtr;    /* Information from the super block */
  3590. d1394 1
  3591. a1394 1
  3592.     Fsdm_SummaryInfo *summaryPtr;    /* Reference to summary info to fill in */
  3593. d1397 1
  3594. a1397 1
  3595.     bzero((Address)summaryPtr, DEV_BYTES_PER_SECTOR);
  3596. d1401 2
  3597. a1402 2
  3598.      * 12 blocks are already allocated, 4 for the root directory,
  3599.      * and 8 more for lost+found.
  3600. d1405 1
  3601. a1405 4
  3602.                 - 12;
  3603.     if (makeFscheckOut) {
  3604.     summaryPtr->numFreeKbytes -= 8;
  3605.     }
  3606. d1407 2
  3607. a1408 2
  3608.      * 4 file descriptors are already used, 0 and 1 are reserved,
  3609.      * 2 is for the root, and 3 is for lost+found.
  3610. d1410 1
  3611. a1410 7
  3612.     summaryPtr->numFreeFileDesc = headerPtr->numFileDesc - 4;
  3613.     if (makeFile) {
  3614.     summaryPtr->numFreeFileDesc--;
  3615.     }
  3616.     if (makeFscheckOut) {
  3617.     summaryPtr->numFreeFileDesc--;
  3618.     }
  3619. d1435 1
  3620. a1435 1
  3621.  * WriteFileDesc --
  3622. d1437 1
  3623. a1437 1
  3624.  *    Write out the file descriptor array to disk.
  3625. d1440 1
  3626. a1440 1
  3627.  *    None.
  3628. d1448 2
  3629. a1449 1
  3630. WriteFileDesc(headerPtr, partFID)
  3631. a1450 1
  3632.     int partFID;    /* File handle for partition to format */
  3633. d1454 1
  3634. a1454 1
  3635.     char *block;
  3636. d1457 1
  3637. d1464 1
  3638. d1470 2
  3639. a1471 3
  3640.      * canned file descriptors for the root, bad block file, and the
  3641.      * lost and found directory.  For (early system) testing an empty file
  3642.      * can also be created.
  3643. a1472 1
  3644.     block = (char *)malloc(FS_BLOCK_SIZE);
  3645. d1483 2
  3646. a1484 1
  3647.         SetBadBlockFileDescriptor(fileDescPtr);
  3648. d1486 6
  3649. a1491 1
  3650.         SetRootFileDescriptor(fileDescPtr);
  3651. d1493 13
  3652. a1505 5
  3653.         SetLostFoundFileDescriptor(fileDescPtr);
  3654.     } else if ((index == FSDM_LOST_FOUND_FILE_NUMBER+1) && makeFile) {
  3655.         SetEmptyFileDescriptor(fileDescPtr);
  3656.     } else if ((index == FSDM_LOST_FOUND_FILE_NUMBER+2) && makeFscheckOut) {
  3657.         SetFscheckOutFileDescriptor(fileDescPtr);
  3658. a1553 303
  3659.  * SetRootFileDescriptor --
  3660.  *
  3661.  *    Set up the file descriptor for the root directory.
  3662.  *
  3663.  * Results:
  3664.  *    Fill in the file descriptor.
  3665.  *
  3666.  * Side effects:
  3667.  *    None.
  3668.  *
  3669.  *----------------------------------------------------------------------
  3670.  */
  3671. void
  3672. SetRootFileDescriptor(fileDescPtr)
  3673.     register Fsdm_FileDescriptor *fileDescPtr;
  3674. {
  3675.     Time time;
  3676.     int index;
  3677.  
  3678.     fileDescPtr->flags = FSDM_FD_ALLOC;
  3679.     fileDescPtr->fileType = FS_DIRECTORY;
  3680.     fileDescPtr->permissions = 0755;
  3681.     fileDescPtr->uid = 0;
  3682.     fileDescPtr->gid = 0;
  3683.     fileDescPtr->lastByte = FS_BLOCK_SIZE-1;
  3684.     fileDescPtr->firstByte = -1;
  3685.     fileDescPtr->numLinks = 3;
  3686.     /*
  3687.      * Can't know device information because that depends on
  3688.      * the way the system is configured.
  3689.      */
  3690.     fileDescPtr->devServerID = -1;
  3691.     fileDescPtr->devType = -1;
  3692.     fileDescPtr->devUnit = -1;
  3693.  
  3694.     /*
  3695.      * Set the time stamps.  This assumes that universal time, not local
  3696.      * time, is used for time stamps.
  3697.      */
  3698.     Sys_GetTimeOfDay(&time, NULL, NULL);
  3699.     fileDescPtr->createTime = time.seconds;
  3700.     fileDescPtr->accessTime = 0;
  3701.     fileDescPtr->descModifyTime = time.seconds;
  3702.     fileDescPtr->dataModifyTime = time.seconds;
  3703.  
  3704.     /*
  3705.      * Place the data in the first filesystem block.
  3706.      */
  3707.     fileDescPtr->direct[0] = 0;
  3708.     for (index = 1; index < FSDM_NUM_DIRECT_BLOCKS ; index++) {
  3709.     fileDescPtr->direct[index] = FSDM_NIL_INDEX;
  3710.     }
  3711.     for (index = 0; index < FSDM_NUM_INDIRECT_BLOCKS ; index++) {
  3712.     fileDescPtr->indirect[index] = FSDM_NIL_INDEX;
  3713.     }
  3714.     fileDescPtr->numKbytes = 4;
  3715.     fileDescPtr->version = 1;
  3716. }
  3717.  
  3718. /*
  3719.  *----------------------------------------------------------------------
  3720.  *
  3721.  * SetBadBlockFileDescriptor --
  3722.  *
  3723.  *    Set up the file descriptor for the bad block file.
  3724.  *
  3725.  * Results:
  3726.  *    Fill in the file descriptor.
  3727.  *
  3728.  * Side effects:
  3729.  *    None.
  3730.  *
  3731.  *----------------------------------------------------------------------
  3732.  */
  3733. void
  3734. SetBadBlockFileDescriptor(fileDescPtr)
  3735.     register Fsdm_FileDescriptor *fileDescPtr;
  3736. {
  3737.     Time time;
  3738.     int index;
  3739.  
  3740.     fileDescPtr->flags = FSDM_FD_ALLOC;
  3741.     fileDescPtr->fileType = FS_FILE;
  3742.     fileDescPtr->permissions = 0000;
  3743.     fileDescPtr->uid = 0;
  3744.     fileDescPtr->gid = 0;
  3745.     fileDescPtr->lastByte = -1;
  3746.     fileDescPtr->firstByte = -1;
  3747.     fileDescPtr->numLinks = 0;        /* Intentionally unreferenced */
  3748.     /*
  3749.      * Can't know device information because that depends on
  3750.      * the way the system is configured.
  3751.      */
  3752.     fileDescPtr->devServerID = -1;
  3753.     fileDescPtr->devType = -1;
  3754.     fileDescPtr->devUnit = -1;
  3755.  
  3756.     /*
  3757.      * Set the time stamps.  This assumes that universal time, not local
  3758.      * time, is used for time stamps.
  3759.      */
  3760.     Sys_GetTimeOfDay(&time, NULL, NULL);
  3761.     fileDescPtr->createTime = time.seconds;
  3762.     fileDescPtr->accessTime = 0;
  3763.     fileDescPtr->descModifyTime = time.seconds;
  3764.     fileDescPtr->dataModifyTime = time.seconds;
  3765.  
  3766.     /*
  3767.      * Place the data in the first filesystem block.
  3768.      */
  3769.     for (index = 0; index < FSDM_NUM_DIRECT_BLOCKS ; index++) {
  3770.     fileDescPtr->direct[index] = FSDM_NIL_INDEX;
  3771.     }
  3772.     for (index = 0; index < FSDM_NUM_INDIRECT_BLOCKS ; index++) {
  3773.     fileDescPtr->indirect[index] = FSDM_NIL_INDEX;
  3774.     }
  3775.     fileDescPtr->numKbytes = 0;
  3776.     fileDescPtr->version = 1;
  3777. }
  3778.  
  3779. /*
  3780.  *----------------------------------------------------------------------
  3781.  *
  3782.  * SetLostFoundFileDescriptor --
  3783.  *
  3784.  *    Set up the file descriptor for the lost and found directory.
  3785.  *
  3786.  * Results:
  3787.  *    Fill in the file descriptor.
  3788.  *
  3789.  * Side effects:
  3790.  *    None.
  3791.  *
  3792.  *----------------------------------------------------------------------
  3793.  */
  3794. void
  3795. SetLostFoundFileDescriptor(fileDescPtr)
  3796.     register Fsdm_FileDescriptor *fileDescPtr;
  3797. {
  3798.     Time time;
  3799.     int index;
  3800.  
  3801.     fileDescPtr->flags = FSDM_FD_ALLOC;
  3802.     fileDescPtr->fileType = FS_DIRECTORY;
  3803.     fileDescPtr->permissions = 0755;
  3804.     fileDescPtr->uid = 0;
  3805.     fileDescPtr->gid = 0;
  3806.     fileDescPtr->lastByte = FSDM_NUM_LOST_FOUND_BLOCKS * FS_BLOCK_SIZE - 1;
  3807.     fileDescPtr->firstByte = -1;
  3808.     fileDescPtr->numLinks = 2;
  3809.     /*
  3810.      * Can't know device information because that depends on
  3811.      * the way the system is configured.
  3812.      */
  3813.     fileDescPtr->devServerID = -1;
  3814.     fileDescPtr->devType = -1;
  3815.     fileDescPtr->devUnit = -1;
  3816.  
  3817.     /*
  3818.      * Set the time stamps.  This assumes that universal time, not local
  3819.      * time, is used for time stamps.
  3820.      */
  3821.     Sys_GetTimeOfDay(&time, NULL, NULL);
  3822.     fileDescPtr->createTime = time.seconds;
  3823.     fileDescPtr->accessTime = 0;
  3824.     fileDescPtr->descModifyTime = time.seconds;
  3825.     fileDescPtr->dataModifyTime = time.seconds;
  3826.  
  3827.     for (index = 0; index < FSDM_NUM_LOST_FOUND_BLOCKS ; index++) {
  3828.     fileDescPtr->direct[index] = FS_FRAGMENTS_PER_BLOCK * (index + 1);
  3829.     }
  3830.     for (; index < FSDM_NUM_DIRECT_BLOCKS ; index++) {
  3831.     fileDescPtr->direct[index] = FSDM_NIL_INDEX;
  3832.     }
  3833.     for (index = 0; index < FSDM_NUM_INDIRECT_BLOCKS ; index++) {
  3834.     fileDescPtr->indirect[index] = FSDM_NIL_INDEX;
  3835.     }
  3836.     fileDescPtr->numKbytes = 8;
  3837.     fileDescPtr->version = 1;
  3838. }
  3839.  
  3840. /*
  3841.  *----------------------------------------------------------------------
  3842.  *
  3843.  * SetEmptyFileDescriptor --
  3844.  *
  3845.  *    Set up a file descriptor for an empty file.
  3846.  *
  3847.  * Results:
  3848.  *    Fill in the file descriptor.
  3849.  *
  3850.  * Side effects:
  3851.  *    None.
  3852.  *
  3853.  *----------------------------------------------------------------------
  3854.  */
  3855. void
  3856. SetEmptyFileDescriptor(fileDescPtr)
  3857.     register Fsdm_FileDescriptor *fileDescPtr;
  3858. {
  3859.     Time time;
  3860.     int index;
  3861.  
  3862.     fileDescPtr->flags = FSDM_FD_ALLOC;
  3863.     fileDescPtr->fileType = FS_FILE;
  3864.     fileDescPtr->permissions = 0666;
  3865.     fileDescPtr->uid = 0;
  3866.     fileDescPtr->gid = 0;
  3867.     fileDescPtr->lastByte = -1;
  3868.     fileDescPtr->firstByte = -1;
  3869.     fileDescPtr->numLinks = 1;
  3870.     /*
  3871.      * Can't know device information because that depends on
  3872.      * the way the system is configured.
  3873.      */
  3874.     fileDescPtr->devServerID = -1;
  3875.     fileDescPtr->devType = -1;
  3876.     fileDescPtr->devUnit = -1;
  3877.  
  3878.     /*
  3879.      * Set the time stamps.  This assumes that universal time, not local
  3880.      * time, is used for time stamps.
  3881.      */
  3882.     Sys_GetTimeOfDay(&time, NULL, NULL);
  3883.     fileDescPtr->createTime = time.seconds;
  3884.     fileDescPtr->accessTime = 0;
  3885.     fileDescPtr->descModifyTime = time.seconds;
  3886.     fileDescPtr->dataModifyTime = time.seconds;
  3887.  
  3888.     for (index = 0; index < FSDM_NUM_DIRECT_BLOCKS ; index++) {
  3889.     fileDescPtr->direct[index] = FSDM_NIL_INDEX;
  3890.     }
  3891.     for (index = 0; index < FSDM_NUM_INDIRECT_BLOCKS ; index++) {
  3892.     fileDescPtr->indirect[index] = FSDM_NIL_INDEX;
  3893.     }
  3894.     fileDescPtr->numKbytes = 0;
  3895.     fileDescPtr->version = 1;
  3896. }
  3897.  
  3898. /*
  3899.  *----------------------------------------------------------------------
  3900.  *
  3901.  * SetFscheckOutFileDescriptor --
  3902.  *
  3903.  *    Set up the file descriptor for the .fscheck.out file.
  3904.  *
  3905.  * Results:
  3906.  *    Fill in the file descriptor.
  3907.  *
  3908.  * Side effects:
  3909.  *    None.
  3910.  *
  3911.  *----------------------------------------------------------------------
  3912.  */
  3913. void
  3914. SetFscheckOutFileDescriptor(fileDescPtr)
  3915.     register Fsdm_FileDescriptor *fileDescPtr;
  3916. {
  3917.     Time time;
  3918.     int index;
  3919.  
  3920.     fileDescPtr->flags = FSDM_FD_ALLOC;
  3921.     fileDescPtr->fileType = FS_FILE;
  3922.     fileDescPtr->permissions = 0755;
  3923.     fileDescPtr->uid = 0;
  3924.     fileDescPtr->gid = 0;
  3925.     fileDescPtr->lastByte = 2 * FS_BLOCK_SIZE - 1;
  3926.     fileDescPtr->firstByte = -1;
  3927.     fileDescPtr->numLinks = 1;
  3928.     /*
  3929.      * Can't know device information because that depends on
  3930.      * the way the system is configured.
  3931.      */
  3932.     fileDescPtr->devServerID = -1;
  3933.     fileDescPtr->devType = -1;
  3934.     fileDescPtr->devUnit = -1;
  3935.  
  3936.     /*
  3937.      * Set the time stamps.  This assumes that universal time, not local
  3938.      * time, is used for time stamps.
  3939.      */
  3940.     Sys_GetTimeOfDay(&time, NULL, NULL);
  3941.     fileDescPtr->createTime = time.seconds;
  3942.     fileDescPtr->accessTime = 0;
  3943.     fileDescPtr->descModifyTime = time.seconds;
  3944.     fileDescPtr->dataModifyTime = time.seconds;
  3945.  
  3946.     for (index = 0; index < 2 ; index++) {
  3947.     fileDescPtr->direct[index] = FS_FRAGMENTS_PER_BLOCK * (index + 3);
  3948.     }
  3949.     for (; index < FSDM_NUM_DIRECT_BLOCKS ; index++) {
  3950.     fileDescPtr->direct[index] = FSDM_NIL_INDEX;
  3951.     }
  3952.     for (index = 0; index < FSDM_NUM_INDIRECT_BLOCKS ; index++) {
  3953.     fileDescPtr->indirect[index] = FSDM_NIL_INDEX;
  3954.     }
  3955.     fileDescPtr->numKbytes = 8;
  3956.     fileDescPtr->version = 1;
  3957. }
  3958.  
  3959. /*
  3960.  *----------------------------------------------------------------------
  3961.  *
  3962. d1581 1
  3963. a1581 1
  3964.      * Reserve file descriptors 0, 1, 2, and 3.  File number 0 is not used at 
  3965. d1583 1
  3966. a1583 1
  3967.      * File number 2 (FSDM_ROOT_FILE_NUMBER) is the root directory of the domain.
  3968. d1586 1
  3969. d1590 2
  3970. a1591 14
  3971.     bitmap[0] |= 0xf0;
  3972.  
  3973.     /*
  3974.      * Reserve file descriptor # 4 for an empty file.
  3975.      */
  3976.     if (makeFile) {
  3977.     bitmap[0] |= 0x08;
  3978.     }
  3979.     /*
  3980.      * Reserve file descriptor #5 for .fscheck.out.
  3981.      */
  3982.     if (makeFscheckOut) {
  3983.     bitmap[0] |= 0x04;
  3984.     }
  3985. d1626 2
  3986. a1627 2
  3987.  *    first 1K fragment is allocated to the root directory and 8K is
  3988.  *    allocated to lost and found.
  3989. d1638 2
  3990. a1639 1
  3991. WriteBitmap(headerPtr, partFID)
  3992. a1640 1
  3993.     int partFID;
  3994. d1648 3
  3995. a1650 2
  3996.      * Set the bit corresponding to the 4K used for the root directory
  3997.      * and the next 8K reserved for lost and found.
  3998. d1657 3
  3999. a1659 5
  4000.     bitmap[1] |= 0xf0;
  4001.     if (makeFscheckOut) {
  4002.     bitmap[1] |= 0x0f;
  4003.     bitmap[2] |= 0xf0;
  4004.     }
  4005. d1686 4
  4006. a1689 3
  4007. WriteRootDirectory(headerPtr, partFID)
  4008.     register Fsdm_DomainHeader *headerPtr;
  4009.     int partFID;
  4010. d1691 5
  4011. a1695 80
  4012.     ReturnStatus status;
  4013.     char *block;
  4014.     Fslcl_DirEntry *dirEntryPtr;
  4015.     char *fileName;
  4016.     int length;
  4017.     int offset;
  4018.     int i;
  4019.  
  4020.     block = (char *)malloc(FS_BLOCK_SIZE);
  4021.     dirEntryPtr = (Fslcl_DirEntry *)block;
  4022.  
  4023.     fileName = ".";
  4024.     length = strlen(fileName);
  4025.     dirEntryPtr->fileNumber = FSDM_ROOT_FILE_NUMBER;
  4026.     dirEntryPtr->recordLength = Fslcl_DirRecLength(length);
  4027.     dirEntryPtr->nameLength = length;
  4028.     strcpy(dirEntryPtr->fileName, fileName);
  4029.     offset = dirEntryPtr->recordLength;
  4030.  
  4031.     dirEntryPtr = (Fslcl_DirEntry *)((int)block + offset);
  4032.     fileName = "..";
  4033.     length = strlen(fileName);
  4034.     dirEntryPtr->fileNumber = FSDM_ROOT_FILE_NUMBER;
  4035.     dirEntryPtr->recordLength = Fslcl_DirRecLength(length);
  4036.     dirEntryPtr->nameLength = length;
  4037.     strcpy(dirEntryPtr->fileName, fileName);
  4038.     offset += dirEntryPtr->recordLength;
  4039.  
  4040.     /*
  4041.      * Add lost and found.
  4042.      */
  4043.  
  4044.     dirEntryPtr = (Fslcl_DirEntry *) ((int)block + offset);
  4045.     fileName = "lost+found";
  4046.     length = strlen(fileName);
  4047.     dirEntryPtr->fileNumber = FSDM_LOST_FOUND_FILE_NUMBER;
  4048.     dirEntryPtr->nameLength = length;
  4049.     strcpy(dirEntryPtr->fileName, fileName);
  4050.  
  4051.     /*
  4052.      * Add empty file.
  4053.      */
  4054.     if (makeFile) {
  4055.     dirEntryPtr->recordLength = Fslcl_DirRecLength(length);
  4056.     offset += dirEntryPtr->recordLength;
  4057.     dirEntryPtr = (Fslcl_DirEntry *)((int)block + offset);
  4058.     fileName = "testFile";
  4059.     length = strlen(fileName);
  4060.     dirEntryPtr->fileNumber = FSDM_LOST_FOUND_FILE_NUMBER + 1;
  4061.     dirEntryPtr->nameLength = length;
  4062.     strcpy(dirEntryPtr->fileName, fileName);
  4063.     }
  4064.     /*
  4065.      * Add .fscheck.out
  4066.      */
  4067.     if (!makeFscheckOut) {
  4068.     dirEntryPtr->recordLength = FSLCL_DIR_BLOCK_SIZE - offset;
  4069.     } else {
  4070.     dirEntryPtr->recordLength = Fslcl_DirRecLength(length);
  4071.     offset += dirEntryPtr->recordLength;
  4072.     dirEntryPtr = (Fslcl_DirEntry *)((int)block + offset);
  4073.     fileName = fscheckOutName;
  4074.     length = strlen(fileName);
  4075.     dirEntryPtr->fileNumber = FSDM_LOST_FOUND_FILE_NUMBER + 2;
  4076.     dirEntryPtr->nameLength = length;
  4077.     strcpy(dirEntryPtr->fileName, fileName);
  4078.     dirEntryPtr->recordLength = FSLCL_DIR_BLOCK_SIZE - offset;
  4079.     }
  4080.  
  4081.     /*
  4082.      * Fill out the rest of the directory with empty blocks.
  4083.      */
  4084.  
  4085.     for (dirEntryPtr = (Fslcl_DirEntry *)&block[FSLCL_DIR_BLOCK_SIZE], i = 1; 
  4086.      i < FS_BLOCK_SIZE / FSLCL_DIR_BLOCK_SIZE;
  4087.      i++,dirEntryPtr=(Fslcl_DirEntry *)((int)dirEntryPtr + FSLCL_DIR_BLOCK_SIZE)) {
  4088.      dirEntryPtr->fileNumber = 0;
  4089.      dirEntryPtr->recordLength = FSLCL_DIR_BLOCK_SIZE;
  4090.      dirEntryPtr->nameLength = 0;
  4091.     }
  4092. d1697 1
  4093. d1699 1
  4094. d1702 1
  4095. a1702 10
  4096.     dirEntryPtr = (Fslcl_DirEntry *)block;
  4097.     Disk_PrintDirEntry(dirEntryPtr);
  4098.     offset += dirEntryPtr->recordLength;
  4099.     dirEntryPtr = (Fslcl_DirEntry *)((int)block + offset);
  4100.     Disk_PrintDirEntry(dirEntryPtr);
  4101.     offset += dirEntryPtr->recordLength;
  4102.     dirEntryPtr = (Fslcl_DirEntry *)((int)block + offset);
  4103.     Disk_PrintDirEntry(dirEntryPtr);
  4104.     if (makeFile) {
  4105.         offset += dirEntryPtr->recordLength;
  4106. a1704 2
  4107.     }
  4108.     if (makeFscheckOut) {
  4109. a1705 2
  4110.         dirEntryPtr = (Fslcl_DirEntry *)((int)block + offset);
  4111.         Disk_PrintDirEntry(dirEntryPtr);
  4112. a1706 1
  4113.     status = SUCCESS;
  4114. d1708 25
  4115. a1732 7
  4116.     /*
  4117.      * This write trounces the data beyond the stuff allocated to
  4118.      * the root directory.  Currently this is ok and is done because
  4119.      * BlockWrite writes whole numbers of filesystem blocks.
  4120.      */
  4121.     status = Disk_BlockWrite(partFID, headerPtr, headerPtr->dataOffset, 1,
  4122.                        block);
  4123. d1734 1
  4124. d1754 2
  4125. a1755 1
  4126. WriteLostFoundDirectory(headerPtr, partFID)
  4127. d1757 56
  4128. a1812 1
  4129.     int partFID;
  4130. d1814 354
  4131. a2167 7
  4132.     ReturnStatus status;
  4133.     char *block;
  4134.     Fslcl_DirEntry *dirEntryPtr;
  4135.     char *fileName;
  4136.     int length;
  4137.     int offset;
  4138.     int    i;
  4139. d2169 69
  4140. a2237 2
  4141.     block = (char *)malloc(FSDM_NUM_LOST_FOUND_BLOCKS * FS_BLOCK_SIZE);
  4142.     dirEntryPtr = (Fslcl_DirEntry *)block;
  4143. d2239 1
  4144. d2242 1
  4145. a2242 1
  4146.     dirEntryPtr->fileNumber = FSDM_LOST_FOUND_FILE_NUMBER;
  4147. d2248 1
  4148. a2248 1
  4149.     dirEntryPtr = (Fslcl_DirEntry *)((int)block + offset);
  4150. d2251 1
  4151. a2251 1
  4152.     dirEntryPtr->fileNumber = FSDM_ROOT_FILE_NUMBER;
  4153. a2254 1
  4154.  
  4155. d2258 2
  4156. a2259 3
  4157.  
  4158.     for (dirEntryPtr = (Fslcl_DirEntry *)&block[FSLCL_DIR_BLOCK_SIZE], i = 1; 
  4159.      i < FSDM_NUM_LOST_FOUND_BLOCKS * FS_BLOCK_SIZE / FSLCL_DIR_BLOCK_SIZE;
  4160. d2265 31
  4161. a2295 9
  4162.     if (printOnly) {
  4163.     printf("Lost+found Directory\n");
  4164.     offset = 0;
  4165.     dirEntryPtr = (Fslcl_DirEntry *)block;
  4166.     Disk_PrintDirEntry(dirEntryPtr);
  4167.     offset += dirEntryPtr->recordLength;
  4168.     dirEntryPtr = (Fslcl_DirEntry *)((int)block + offset);
  4169.     Disk_PrintDirEntry(dirEntryPtr);
  4170.     status = SUCCESS;
  4171. d2297 1
  4172. a2297 2
  4173.     status = Disk_BlockWrite(partFID, headerPtr, headerPtr->dataOffset + 1,
  4174.                 FSDM_NUM_LOST_FOUND_BLOCKS, block);
  4175. a2298 1
  4176.     return(status);
  4177. d2300 22
  4178. d2323 44
  4179. d2371 1
  4180. a2371 1
  4181.  * Prompt --
  4182. d2373 1
  4183. a2373 1
  4184.  *    Used to prompt the user for an answer. 
  4185. d2376 18
  4186. a2393 53
  4187.  *    1 if the user actually entered something, 0 if he just pressed
  4188.  *    return.  If 0 is returned then answerPtr is untouched.
  4189.  *
  4190.  * Side effects:
  4191.  *    Stuff is written to stdout and read from stdin.
  4192.  *    Memory is allocated.
  4193.  *
  4194.  *----------------------------------------------------------------------
  4195.  */
  4196.  
  4197. int
  4198. Prompt(prompt, options, example, canFree, canAllocate, answerPtr)
  4199.     char     *prompt;    /* Stuff to print first.*/
  4200.     char    *options;    /* Printed inside []'s. */
  4201.     char    *example;    /* Example answer. */
  4202.     Boolean    canFree;    /* Can I free the memory associated with the
  4203.                  * answerPtr? */
  4204.     Boolean    canAllocate;    /* Can I allocate memory to be pointed to by
  4205.                  * answerPtr? */
  4206.     char    **answerPtr;    /* Ptr to place to store answer. */
  4207. {
  4208.     int        n;
  4209.     static char    buffer[100];
  4210.     static char    buffer2[100];
  4211.  
  4212.     assert(!((canFree == TRUE) && (canAllocate == FALSE)));
  4213.     printf("%s", prompt);
  4214.     if (example != NULL && *example != '\0') {
  4215.     printf(", ex. \"%s\"", example);
  4216.     }
  4217.     if (options != NULL && *options != '\0') {
  4218.     printf(", [%s]", options);
  4219.     }
  4220.     if (*answerPtr != NULL && **answerPtr != '\0') {
  4221.     printf(" (%s)", *answerPtr);
  4222.     }
  4223.     printf(" : ");
  4224.     if (fgets(buffer, 100, stdin) == NULL) {
  4225.     exit(0);
  4226.     }
  4227.     n = sscanf(buffer, "%s", buffer2);
  4228.     if (n < 1) {
  4229.     return 0;
  4230.     }
  4231.     if (canFree) {
  4232.     free(*answerPtr);
  4233.     }
  4234.     if (canAllocate) {
  4235.     *answerPtr = malloc(strlen(buffer)+1);
  4236.     }  
  4237.     assert(*answerPtr != NULL);
  4238.     strcpy(*answerPtr, buffer2);
  4239.     return 1;
  4240. @
  4241.  
  4242.  
  4243. 1.14
  4244. log
  4245. @new scsi disk mapping, converted to new fs structure
  4246. @
  4247. text
  4248. @d11 1
  4249. a11 1
  4250. static char rcsid[] = "$Header: /sprite/src/admin/fsmake/RCS/fsmake.c,v 1.13 89/08/29 17:12:52 jhh Exp $ SPRITE (Berkeley)";
  4251. d22 2
  4252. d66 1
  4253. a66 1
  4254. char defaultDevDirectory[] = "/dev/";
  4255. d107 13
  4256. d170 4
  4257. d175 204
  4258. a378 1
  4259.     (void)Opt_Parse(argc, argv,optionArray, numOptions, 0);
  4260. a380 8
  4261.     if (deviceName == (char *)0) {
  4262.     fprintf(stderr,"Specify device name with -dev option\n");
  4263.     status = FAILURE;
  4264.     }
  4265.     if (partName == (char *)0) {
  4266.     fprintf(stderr,"Specify partition with -part option\n");
  4267.     status = FAILURE;
  4268.     }
  4269. d1913 65
  4270. @
  4271.  
  4272.  
  4273. 1.14.1.1
  4274. log
  4275. @New and improved. Includes functionality from fsinstall
  4276. @
  4277. text
  4278. @d11 1
  4279. a11 1
  4280. static char rcsid[] = "$Header: /user1/jhh/src/cmds/fsmake/RCS/fsmake.c,v 1.14 89/10/03 13:13:03 jhh Exp Locker: jhh $ SPRITE (Berkeley)";
  4281. d14 19
  4282. a32 1
  4283. #include "fsmake.h"
  4284. d41 2
  4285. a53 16
  4286. Boolean repartition = FALSE;    /* If TRUE then the partition map is changed. */
  4287. Boolean reconfig = FALSE;    /* If TRUE then the disk configuration
  4288.                  * is changed. */
  4289. Boolean partdisktab = FALSE;    /* If TRUE then read the partition map from
  4290.                  * the disktab file. */
  4291. Boolean configdisktab = FALSE;    /* If TRUE then read the config information
  4292.                  * from the disktab file, otherwise get the
  4293.                  * disk size information directly from the
  4294.                  * disk and compute the "best" configuration..*/
  4295. char *disktabName = "/etc/disktab"; /* Name of disktab file. */
  4296. char *sizeString = NULL;    /* Size of partitions. */
  4297. char *diskType = NULL;        /* Type of disk (e.g.rz55). */
  4298. char *labelTypeName = NULL;    /* Type of label (e.g. sun). */
  4299. char *dirName = NULL;        /* Name of directory that contains files to
  4300.                  * copy to the disk. */
  4301.  
  4302. a61 1
  4303. char *rawDeviceName;        /* Set to "raw_rsd00", etc */
  4304. d64 1
  4305. a64 1
  4306. char defaultDevDirectory[] = "/dev";
  4307. a73 2
  4308.     {OPT_STRING, "rawdev", (Address)&rawDeviceName,
  4309.     "Required: Name of raw device, eg \"raw_rsd00\""},
  4310. d78 2
  4311. d88 2
  4312. a89 2
  4313.     {OPT_STRING, "devDir", (Address)&devDirectory,
  4314.     "Name of device directory (\"/dev\")"},
  4315. a95 19
  4316.     {OPT_TRUE, "repartition", (Address)&repartition,
  4317.     "Change the partitioning of the disk.  USE ONLY ON EMPTY DISKS"},
  4318.     {OPT_TRUE, "reconfig", (Address) &reconfig,
  4319.     "Change the disk configuration info in label. USE ONLY ON EMPTY DISKS"},
  4320.     {OPT_TRUE, "configdisktab", (Address)&configdisktab,
  4321.     "Reconfigure according to info in disktab file"},
  4322.     {OPT_TRUE, "partdisktab", (Address)&partdisktab,
  4323.     "Repartition according to info in disktab file"},
  4324.     {OPT_STRING, "disktabName", (Address)&disktabName,
  4325.     "Name of the disktab file"},
  4326.     {OPT_STRING, "sizes", (Address)&sizeString,
  4327.     "Size of partitions (as a percentage), eg \"a:25,g:75\""},
  4328.     {OPT_STRING, "disktype", (Address)&diskType,
  4329.     "Type of disk. Used to look up information in disktab file"},
  4330.     {OPT_STRING, "labeltype", (Address)&labelTypeName,
  4331.     "Type of native disk label (sun or dec)"},
  4332.     {OPT_STRING, "dir", (Address)&dirName,
  4333.     "Directory to copy files from"},
  4334.  
  4335. d100 1
  4336. a100 1
  4337.  * Time of day when this program runs.
  4338. d103 2
  4339. a104 13
  4340. struct timeval curTime;
  4341.  
  4342. int            freeFDNum;    /* The currently free file descriptor.*/
  4343. int            freeBlockNum;    /* The currently free data block. */
  4344. unsigned char        *fdBitmapPtr;    /* Pointer to the file descriptor
  4345.                      * bitmap. */
  4346. unsigned char        *cylBitmapPtr;    /* Pointer to the cylinder bit map. */
  4347. int            bytesPerCylinder;/* The number of bytes in
  4348.                       * the bitmap for a cylinder.*/
  4349. Fsdm_DomainHeader     *headerPtr;    /* The domain header. */
  4350. Fsdm_SummaryInfo     *summaryPtr;    /* The summary info. */
  4351.  
  4352. char *myName;
  4353. d109 1
  4354. a109 1
  4355. ReturnStatus SetDomainHeader();
  4356. d119 1
  4357. a119 1
  4358. void WriteFileDescBitmap();
  4359. a121 1
  4360. void Usage();
  4361. a122 2
  4362. extern char *getwd();
  4363.  
  4364. a148 1
  4365.     int rawFID = -1;
  4366. d155 2
  4367. a156 4
  4368.     Disk_NativeLabelType    labelType;    
  4369.     Disk_Label            *labelPtr = NULL;
  4370.     int    sizes[8];
  4371.     int i;
  4372. a157 5
  4373.     myName = argv[0];
  4374.     argc = Opt_Parse(argc, argv,optionArray, numOptions, 0);
  4375.     if (argc > 1) {
  4376.     Usage();
  4377.     }
  4378. a176 37
  4379.     for (i = 0; i < 8; i++) {
  4380.     sizes[i] = 0;
  4381.     }
  4382.     if (sizeString != NULL) {
  4383.     char *cPtr;
  4384.     int part;
  4385.     int size;
  4386.     int n;
  4387.     cPtr = sizeString;
  4388.     while (*cPtr != '\0') {
  4389.         part = (int) (*cPtr - 'a');
  4390.         if (part < 0 || part > 7) {
  4391.         fprintf(stderr, 
  4392.         "Argument to -sizes parameter must start with partition.\n");
  4393.         Usage();
  4394.         }
  4395.         cPtr++;
  4396.         if (*cPtr != ':') {
  4397.         fprintf(stderr, 
  4398.         "Argument to -sizes parameter is missing a ':'.\n");
  4399.         Usage();
  4400.         }
  4401.         cPtr++;
  4402.         n = sscanf(cPtr,"%d",&size);
  4403.         if (n != 1) {
  4404.         fprintf(stderr, 
  4405.     "Argument to -sizes parameter must have an integer following the ':'\n");
  4406.         Usage();
  4407.         }
  4408.         sizes[part] = size;
  4409.         cPtr = strchr(cPtr, ',');
  4410.         if (cPtr == NULL) {
  4411.         break;
  4412.         }
  4413.         cPtr++;
  4414.     }
  4415.     }
  4416. d180 1
  4417. a180 1
  4418.     Host_Entry    *entryPtr;
  4419. d183 1
  4420. a183 6
  4421.         entryPtr = Host_ByID(temp);
  4422.         if (entryPtr == NULL) {
  4423.         fprintf(stderr, 
  4424.             "WARNING: Host %d is not in /etc/spritehosts.\n", temp);
  4425.         }
  4426.         hostID = temp;
  4427. d185 5
  4428. a189 15
  4429.         entryPtr = Host_ByName(hostIDString);
  4430.         if (entryPtr == NULL) {
  4431.         fprintf(stderr, 
  4432.             "Host %s is not in /etc/spritehosts.\n", temp);
  4433.         status = FAILURE;
  4434.         }
  4435.         hostID = entryPtr->id;
  4436.     }
  4437.     }
  4438.     labelType = DISK_NO_LABEL;
  4439.     if (labelTypeName != NULL) {
  4440.     if (!strcasecmp(labelTypeName, "sun")) {
  4441.         labelType = DISK_SUN_LABEL;
  4442.     } else if (!strcasecmp(labelTypeName, "dec")) {
  4443.         labelType = DISK_DEC_LABEL;
  4444. d191 1
  4445. a191 3
  4446.         fprintf(stderr, 
  4447.         "Argument to -labeltype must be \"sun\" or \"dec\"\n");
  4448.         status = FAILURE;
  4449. d194 1
  4450. d202 9
  4451. a210 23
  4452.     sprintf(firstPartitionName, "%s/%s%c", devDirectory, deviceName,
  4453.     *firstPartName);
  4454.     sprintf(partitionName, "%s/%s%c", devDirectory, deviceName,
  4455.     *partName);
  4456.     if (rawDeviceName != NULL) {
  4457.     char buffer[64];
  4458.     sprintf(buffer, "%s/%s", devDirectory, rawDeviceName);
  4459.     if (!printOnly) {
  4460.         rawFID = open(buffer, O_RDWR);
  4461.     } else {
  4462.         rawFID = open(buffer, O_RDONLY);
  4463.     }
  4464.     if (rawFID < 0) {
  4465.         fprintf(stderr, "Can't open raw device %s: ", buffer);
  4466.         perror((char *) NULL);
  4467.         exit(FAILURE);
  4468.     }
  4469.     }
  4470.     if (!printOnly) {
  4471.     firstPartFID = open(firstPartitionName, O_RDWR);
  4472.     } else {
  4473.     firstPartFID = open(firstPartitionName, O_RDONLY);
  4474.     }
  4475. d212 1
  4476. a212 2
  4477.     fprintf(stderr, "Can't open first partition %s: ", firstPartitionName);
  4478.     perror((char *) NULL);
  4479. d231 9
  4480. a239 39
  4481.     if (reconfig) {
  4482.     if (rawFID < 0) {
  4483.         fprintf(stderr, 
  4484.     "You must specify a raw device with the -reconfig flag\n");
  4485.         exit(FAILURE);
  4486.     }
  4487.     status = Reconfig(rawFID, configdisktab, disktabName, diskType,
  4488.         labelType, scsiDisk, &labelPtr);
  4489.     if (status != SUCCESS) {
  4490.         fprintf(stderr, "Reconfiguration of disk failed.\n");
  4491.         exit(1);
  4492.     }
  4493.     }
  4494.     if (repartition || reconfig) {
  4495.     if (rawFID < 0) {
  4496.         fprintf(stderr, 
  4497.     "You must specify a raw device with the -repartition flag\n");
  4498.         exit(FAILURE);
  4499.     }
  4500.     status = Repartition(rawFID, partdisktab, disktabName, diskType,
  4501.         labelType, partition,
  4502.         sizes, &labelPtr);
  4503.     if (status != SUCCESS) {
  4504.         fprintf(stderr, "Repartition of disk failed.\n");
  4505.         exit(1);
  4506.     }
  4507.     printf("New disk label:\n");
  4508.     Disk_PrintLabel(labelPtr);
  4509.     status = ConfirmDiskSize(rawFID, labelPtr, sizes);
  4510.     if (status != SUCCESS) {
  4511.         exit(status);
  4512.     }
  4513.     if (!printOnly) {
  4514.         status = Disk_WriteLabel(rawFID, labelPtr);
  4515.         if (status != SUCCESS) {
  4516.         fprintf(stderr, "Can't write label to raw device\n");
  4517.         exit(status);
  4518.         }
  4519.     }
  4520. a258 1
  4521.     gettimeofday(&curTime, (struct timezone *) NULL);
  4522. d260 2
  4523. a261 21
  4524.     status = MakeFilesystem(firstPartFID, partFID, partition, spriteID, 
  4525.     &labelPtr);
  4526.     if ((status == SUCCESS) && (dirName != NULL)) {
  4527.     Fsdm_FileDescriptor    rootDesc;
  4528.     printf("Copying %s to new filesystem.\n", dirName);
  4529.     fdBitmapPtr = ReadFileDescBitmap(partFID, headerPtr);
  4530.     cylBitmapPtr = ReadBitmap(partFID, headerPtr);
  4531.     ReadFileDesc(partFID, headerPtr, FSDM_ROOT_FILE_NUMBER, &rootDesc);
  4532.     CopyTree(partFID, dirName, FSDM_ROOT_FILE_NUMBER, &rootDesc,
  4533.         FSDM_ROOT_FILE_NUMBER, FALSE, "/");
  4534.     WriteFileDesc(partFID, headerPtr, FSDM_ROOT_FILE_NUMBER, &rootDesc);
  4535.     if (!printOnly) {
  4536.         status = Disk_WriteSummaryInfo(partFID, labelPtr, summaryPtr);
  4537.         if (status != 0) {
  4538.         perror("Summary sector write failed (2)");
  4539.         exit(status);
  4540.         }
  4541.         WriteFileDescBitmap(partFID, headerPtr, fdBitmapPtr);
  4542.         WriteBitmap(partFID, headerPtr);
  4543.     }
  4544.     }
  4545. a271 23
  4546.  * Usage --
  4547.  *
  4548.  *    Prints out the correct command syntax and exits..
  4549.  *
  4550.  * Results:
  4551.  *    None.
  4552.  *
  4553.  * Side effects:
  4554.  *    The program exits.
  4555.  *
  4556.  *----------------------------------------------------------------------
  4557.  */
  4558.  
  4559. void
  4560. Usage()
  4561. {
  4562.     Opt_PrintUsage(myName, optionArray, Opt_Number(optionArray));
  4563.     exit(1);
  4564. }
  4565.  
  4566. /*
  4567.  *----------------------------------------------------------------------
  4568.  *
  4569. d285 1
  4570. a285 1
  4571. MakeFilesystem(firstPartFID, partFID, partition, spriteID, labelPtrPtr)
  4572. a290 1
  4573.     Disk_Label    **labelPtrPtr; /* Ptr to ptr to disk label. */
  4574. d293 23
  4575. a315 11
  4576.     Fsdm_DomainHeader    oldDomainHeader;
  4577.     Fsdm_SummaryInfo    oldSummaryInfo;
  4578.     Fsdm_FileDescriptor rootFD;
  4579.     Fsdm_FileDescriptor *rootFDPtr = &rootFD;
  4580.     Disk_Label    *labelPtr = *labelPtrPtr;
  4581.  
  4582.     if (labelPtr == NULL) {
  4583.     labelPtr = Disk_ReadLabel(firstPartFID);
  4584.     if (labelPtr == NULL) {
  4585.         fprintf(stderr, "Unable to read disk label.\n");
  4586.         return FAILURE;
  4587. d317 1
  4588. a317 4
  4589.     }
  4590.     *labelPtrPtr = labelPtr;
  4591.     summaryPtr = Disk_ReadSummaryInfo(partFID, labelPtr);
  4592.     if (summaryPtr != NULL) {
  4593. a318 2
  4594.         char answer[10];
  4595.  
  4596. d320 1
  4597. a320 1
  4598.         summaryPtr->domainPrefix);
  4599. d326 1
  4600. a326 1
  4601.         return SUCCESS;
  4602. d330 7
  4603. a336 4
  4604.     bzero((char *) &oldDomainHeader, sizeof(oldDomainHeader));
  4605.     bzero((char *) &oldSummaryInfo, sizeof(oldSummaryInfo));
  4606.     if (!printOnly) {
  4607.     status = Disk_WriteDomainHeader(partFID, labelPtr, &oldDomainHeader);
  4608. d338 2
  4609. a339 1
  4610.         printf("Clear of old domain header failed\n");
  4611. d341 7
  4612. a347 3
  4613.     status = Disk_WriteSummaryInfo(partFID, labelPtr, &oldSummaryInfo);
  4614.     if (status != SUCCESS) {
  4615.         printf("Clear of old summary info failed\n");
  4616. d354 10
  4617. a363 15
  4618.     labelPtr->summarySector = bootSectors + 1;
  4619.     labelPtr->domainSector = bootSectors + 2;
  4620.     labelPtr->numBootSectors = bootSectors;
  4621.     } else {
  4622.     Disk_Label *newLabelPtr;
  4623.     newLabelPtr = Disk_NewLabel(labelPtr->labelType);
  4624.     labelPtr->summarySector = newLabelPtr->summarySector;
  4625.     labelPtr->domainSector = newLabelPtr->domainSector;
  4626.     labelPtr->numBootSectors = newLabelPtr->numBootSectors;
  4627.     free((char *) newLabelPtr);
  4628.     }
  4629.     headerPtr = (Fsdm_DomainHeader *) malloc(sizeof(Fsdm_DomainHeader));
  4630.     status = SetDomainHeader(labelPtr, headerPtr, spriteID, partition);
  4631.     if (status != SUCCESS) {
  4632.     return FAILURE;
  4633. d365 3
  4634. d371 9
  4635. a379 1
  4636.     status = Disk_WriteLabel(partFID, labelPtr);
  4637. d381 1
  4638. a381 1
  4639.         perror("Disk label write failed"); 
  4640. d384 7
  4641. a390 1
  4642.     status = Disk_WriteDomainHeader(partFID, labelPtr, headerPtr);
  4643. d392 1
  4644. a392 1
  4645.         perror("DomainHeader write failed");
  4646. d396 2
  4647. a397 3
  4648.     summaryPtr = (Fsdm_SummaryInfo *) malloc(DEV_BYTES_PER_SECTOR);
  4649.     SetSummaryInfo(headerPtr, summaryPtr);
  4650.     status = WriteAllFileDescs(partFID, headerPtr);
  4651. d399 1
  4652. a399 1
  4653.     perror("WriteAllFileDescs failed");
  4654. d402 1
  4655. a402 1
  4656.     status = WriteBitmap(partFID, headerPtr);
  4657. d407 1
  4658. a407 3
  4659.     ReadFileDesc(partFID, headerPtr, FSDM_ROOT_FILE_NUMBER, rootFDPtr);
  4660.     status = WriteRootDirectory(partFID, headerPtr, rootFDPtr);
  4661.     WriteFileDesc(partFID, headerPtr, FSDM_ROOT_FILE_NUMBER, rootFDPtr);
  4662. d412 1
  4663. a412 1
  4664.     status = WriteLostFoundDirectory(partFID, headerPtr);
  4665. d423 1
  4666. a423 1
  4667.  * CopyTree --
  4668. d425 8
  4669. a432 2
  4670.  *    Copy the tree of files in the given directory
  4671.  *    the disk table.
  4672. d434 9
  4673. a442 46
  4674.  * Results:
  4675.  *    A pointer to a disk info struct.
  4676.  *
  4677.  * Side effects:
  4678.  *    Disk info struct malloc'd and initialized.  The disk header will be
  4679.  *    written if is successfully set up.
  4680.  *
  4681.  *----------------------------------------------------------------------
  4682.  */
  4683. void
  4684. CopyTree(partFID, dirName, dirFDNum, dirFDPtr, parentFDNum, createDir, path)
  4685.     int            partFID;    /* Handle on raw disk. */
  4686.     char        *dirName;    /* Name of directory to copy. */
  4687.     int            dirFDNum;    /* File number of directory. */
  4688.     Fsdm_FileDescriptor    *dirFDPtr;    /* File descriptor of directory. */
  4689.     int            parentFDNum;    /* File number of parent. */
  4690.     Boolean        createDir;    /* Should create the directory. */
  4691.     char        *path;
  4692. {
  4693.     DIR            *unixDirPtr;
  4694.     Fslcl_DirEntry    *unixDirEntPtr;
  4695.     DirIndexInfo    indexInfo;
  4696.     Fslcl_DirEntry    *spriteDirEntPtr;
  4697.     char        fileName[FS_MAX_NAME_LENGTH + 1];
  4698.     int            newFDNum;
  4699.     Fsdm_FileDescriptor    newFD;
  4700.     Fsdm_FileDescriptor    *newFDPtr;
  4701.     struct    stat    statBuf;
  4702.     int            followLinks;
  4703.     char        pathName[1024];
  4704.     char        fileBlock[FS_BLOCK_SIZE];
  4705.     char        indirectBlock[FS_BLOCK_SIZE];
  4706.     int            *indIndexPtr = (int *)indirectBlock;
  4707.     char        *suffix;
  4708.     Boolean        makeDevice;
  4709.     int            devType;
  4710.     int            devUnit;
  4711.     int            devServer;
  4712.     ReturnStatus    status;
  4713.     
  4714.  
  4715.     /*
  4716.      * Get our absolute path name so we can get back if we follow a
  4717.      * symbolic link.
  4718.      */
  4719.     (void) getwd(pathName);
  4720. d444 1
  4721. a444 81
  4722.     if (chdir(dirName) < 0) {
  4723.     perror(dirName);
  4724.     exit(1);
  4725.     }
  4726.  
  4727.     /*
  4728.      * Get a pointer to the UNIX directory.
  4729.      */
  4730.     unixDirPtr = opendir(".");
  4731.     if (unixDirPtr == NULL) {
  4732.     fprintf(stderr, "Can't open directory %s\n", dirName);
  4733.     exit(1);
  4734.     }
  4735.     /*
  4736.      * Open the Sprite directory.
  4737.      */
  4738.     status = OpenDir(partFID, headerPtr, dirFDPtr, &indexInfo,&spriteDirEntPtr);
  4739.     if (status != SUCCESS) {
  4740.     if (chdir(pathName) < 0) {
  4741.         perror(pathName);
  4742.         exit(1);
  4743.     }
  4744.     }
  4745.     /*
  4746.      * See if there is a "follow.links" file in this directory.  If so
  4747.      * we are supposed to follow symbolic links rather than just copying
  4748.      * the links.
  4749.      */
  4750.     if (stat("follow.links", &statBuf) < 0) {
  4751.     followLinks = 0;
  4752.     } else {
  4753.     printf("Following links ...\n");
  4754.     followLinks = 1;
  4755.     }
  4756.     if (createDir) {
  4757.     CreateDir(indexInfo.dirBlock, 1, dirFDNum, parentFDNum);
  4758.     }
  4759.  
  4760.     for (unixDirEntPtr = (Fslcl_DirEntry *)readdir(unixDirPtr);
  4761.        unixDirEntPtr != NULL;
  4762.        unixDirEntPtr = (Fslcl_DirEntry *)readdir(unixDirPtr)) {
  4763.  
  4764.     if (unixDirEntPtr->nameLength == 1 && 
  4765.         strncmp(unixDirEntPtr->fileName, ".", 1) == 0) {
  4766.         continue;
  4767.     }
  4768.     if (unixDirEntPtr->nameLength == 2 && 
  4769.         strncmp(unixDirEntPtr->fileName, "..", 2) == 0) {
  4770.         continue;
  4771.     }
  4772.     strncpy(fileName, unixDirEntPtr->fileName, unixDirEntPtr->nameLength);
  4773.     fileName[unixDirEntPtr->nameLength] = 0;
  4774.     if (followLinks) {
  4775.         if (stat(fileName, &statBuf) < 0) {
  4776.         perror(fileName);
  4777.         exit(1);
  4778.         }
  4779.     } else {
  4780.         if (lstat(fileName, &statBuf) < 0) {
  4781.         perror(fileName);
  4782.         exit(1);
  4783.         }
  4784.     }
  4785.     makeDevice = FALSE;
  4786.     suffix = strstr(fileName, DEVICE_SUFFIX);
  4787.     if ((suffix != NULL) && (!strcmp(suffix, DEVICE_SUFFIX)) &&
  4788.         ((statBuf.st_mode & S_GFMT) == S_GFREG)) {
  4789.         FILE    *fp;
  4790.         char    buffer[128];
  4791.         int        ok = 0;
  4792.  
  4793.         fp = fopen(fileName, "r");
  4794.         if (fp == NULL) {
  4795.         fprintf(stderr, "WARNING: Can't open %s%s: ", pathName,
  4796.             fileName);
  4797.         perror((char *) NULL);
  4798.         continue;
  4799.         }
  4800.         while (fgets(buffer, 128, fp) != NULL) {
  4801.         char    tmp[128];
  4802.         int    n;
  4803. d446 7
  4804. a452 222
  4805.         n = sscanf(buffer, " %128s", tmp);
  4806.         if (n < 1 || *tmp == '#') {
  4807.             continue;
  4808.         }
  4809.         if (sscanf(buffer, " %d %d %d", &devServer, &devType, &devUnit)
  4810.             != 3) {
  4811.             fprintf(stderr, 
  4812.             "WARNING: Device file %s%s has bad format. Skipping.\n",
  4813.             pathName, fileName);
  4814.             break;
  4815.         }
  4816.         ok = 1;
  4817.         break;
  4818.         }
  4819.         fclose(fp);
  4820.         if (!ok) {
  4821.         continue;
  4822.         }
  4823.         makeDevice = TRUE;
  4824.         *suffix = '\0';
  4825.     }
  4826.     newFDNum = freeFDNum;
  4827.     freeFDNum++;
  4828.     MarkFDBitmap(newFDNum, fdBitmapPtr);
  4829.     summaryPtr->numFreeFileDesc--;
  4830.     ReadFileDesc(partFID, headerPtr, newFDNum, &newFD);
  4831.     newFDPtr = &newFD;
  4832.  
  4833.     status = AddToDirectory(partFID, headerPtr, !printOnly, &indexInfo, 
  4834.         &spriteDirEntPtr, newFDNum, fileName);
  4835.     if (status != SUCCESS) {
  4836.         fprintf(stderr, "%s is full\n", dirName);
  4837.         break;
  4838.     }
  4839.     if (makeDevice) {
  4840.         InitDesc(newFDPtr, FS_DEVICE, 0, devServer, devType, devUnit, 0, 0,
  4841.         (int) statBuf.st_mode & 07777, curTime.tv_sec);
  4842.         printf("Device: %s%s (S %d, T %d, U %d)\n", path, fileName,
  4843.         devServer, devType, devUnit);
  4844. #ifdef sprite
  4845.     } else if ((statBuf.st_mode & S_GFMT) == S_IFPDEV) {
  4846.         printf("Skipping pseudo-device %s%s\n", path, fileName);
  4847. #endif
  4848.     } else if ((statBuf.st_mode & S_GFMT) == S_GFREG ||
  4849. #ifdef sprite
  4850.            ((statBuf.st_mode & S_GFMT) == S_IFRLNK)  || 
  4851. #endif
  4852.            (statBuf.st_mode & S_GFMT) == S_GFLNK) {
  4853.         int    fd;
  4854.         int    blockNum;
  4855.         int    toRead;
  4856.         int    len;
  4857.  
  4858.         blockNum = 0;
  4859.         if ((statBuf.st_mode & S_GFMT) == S_GFREG) {
  4860.         printf("File: %s%s\n", path, fileName);
  4861.         InitDesc(newFDPtr, FS_FILE, (int) statBuf.st_size, -1, -1, -1,
  4862.              0, 0, (int) statBuf.st_mode & 07777, statBuf.st_mtime);
  4863.         /*
  4864.          * Copy the file over.
  4865.          */
  4866.         fd = open(fileName, 0);
  4867.         if (fd < 0) {
  4868.             fprintf(stderr, "WARNING: Can't open %s%s: ", pathName,
  4869.             fileName);
  4870.             perror((char *) NULL);
  4871.             freeFDNum--;
  4872.             summaryPtr->numFreeFileDesc++;
  4873.             continue;
  4874.         }
  4875.         len = read(fd, fileBlock, FS_BLOCK_SIZE);
  4876.         if (len < 0) {
  4877.             fprintf(stderr, "WARNING: Can't read %s%s: ", pathName,
  4878.             fileName);
  4879.             perror((char *) NULL);
  4880.             freeFDNum--;
  4881.             summaryPtr->numFreeFileDesc++;
  4882.             continue;
  4883.         }
  4884.         toRead = statBuf.st_size;
  4885.         } else {
  4886.         len = readlink(fileName, fileBlock, FS_BLOCK_SIZE);
  4887.         if (len < 0) {
  4888.             fprintf(stderr, "WARNING: Can't readlink %s%s: ", pathName,
  4889.             fileName);
  4890.             perror((char *) NULL);
  4891.             freeFDNum--;
  4892.             summaryPtr->numFreeFileDesc++;
  4893.             continue;
  4894.         }
  4895.         fileBlock[len] = '\0';
  4896.         InitDesc(newFDPtr, FS_SYMBOLIC_LINK, len + 1, -1, -1, -1, 
  4897.              0, 0, 0777, statBuf.st_mtime);
  4898. #ifdef sprite
  4899.         if ((statBuf.st_mode & S_GFMT) == S_IFRLNK) { 
  4900.             printf("Remote link: %s%s\n", path, fileName);
  4901.         } else {
  4902.             printf("Symbolic link: %s%s -> %s\n", 
  4903.                 path, fileName, fileBlock);
  4904.         }
  4905. #else
  4906.         printf("Symbolic link: %s%s -> %s\n", 
  4907.             path, fileName, fileBlock);
  4908. #endif
  4909.         toRead = len + 1;
  4910.         }
  4911.  
  4912.         while (len > 0) {
  4913.         if (blockNum == FSDM_NUM_DIRECT_BLOCKS) {
  4914.             int    i;
  4915.             int    *intPtr;
  4916.             /*
  4917.              * Must allocate an indirect block.
  4918.              */
  4919.             newFDPtr->indirect[0] =
  4920.             VirtToPhys(freeBlockNum * FS_FRAGMENTS_PER_BLOCK);
  4921.             MarkDataBitmap(headerPtr, cylBitmapPtr, freeBlockNum,
  4922.                    FS_FRAGMENTS_PER_BLOCK);
  4923.             freeBlockNum++;
  4924.             summaryPtr->numFreeKbytes -= FS_FRAGMENTS_PER_BLOCK;
  4925.             for (i = 0, intPtr = (int *)indirectBlock; 
  4926.              i < FS_BLOCK_SIZE / sizeof(int); 
  4927.              i++, intPtr++) {
  4928.              *intPtr = FSDM_NIL_INDEX;
  4929.             }
  4930.         }
  4931.         if (blockNum >= FSDM_NUM_DIRECT_BLOCKS) {
  4932.             indIndexPtr[blockNum - FSDM_NUM_DIRECT_BLOCKS] = 
  4933.                     freeBlockNum * FS_FRAGMENTS_PER_BLOCK;
  4934.             MarkDataBitmap(headerPtr, cylBitmapPtr, freeBlockNum,
  4935.                    FS_FRAGMENTS_PER_BLOCK);
  4936.             summaryPtr->numFreeKbytes -= FS_FRAGMENTS_PER_BLOCK;
  4937.         } else {
  4938.             newFDPtr->direct[blockNum] = 
  4939.                     freeBlockNum * FS_FRAGMENTS_PER_BLOCK;
  4940.             if (toRead > FS_BLOCK_SIZE) {
  4941.             MarkDataBitmap(headerPtr, cylBitmapPtr, freeBlockNum,
  4942.                        FS_FRAGMENTS_PER_BLOCK);
  4943.             summaryPtr->numFreeKbytes -= FS_FRAGMENTS_PER_BLOCK;
  4944.             } else {
  4945.             MarkDataBitmap(headerPtr, cylBitmapPtr, freeBlockNum,
  4946.                        (toRead - 1) / FS_FRAGMENT_SIZE + 1);
  4947.             summaryPtr->numFreeKbytes -= 
  4948.                     (toRead - 1) / FS_FRAGMENT_SIZE + 1;
  4949.             }
  4950.         }
  4951.         /*
  4952.          * Write the block out to disk.
  4953.          */
  4954.         if (Disk_BlockWrite(partFID, headerPtr, 
  4955.                     headerPtr->dataOffset + freeBlockNum,
  4956.                     1, (Address)fileBlock) != 0) {
  4957.             fprintf(stderr, "Couldn't write file block\n");
  4958.             exit(1);
  4959.         }
  4960.         blockNum++;
  4961.         freeBlockNum++;
  4962.         if ((statBuf.st_mode & S_GFMT) == S_GFLNK) {
  4963.             break;
  4964.         }
  4965.         toRead -= len;
  4966.         len = read(fd, fileBlock, FS_BLOCK_SIZE);
  4967.         if (len < 0) {
  4968.             perror(fileName);
  4969.             exit(1);
  4970.         }
  4971.         }
  4972.         if (newFDPtr->indirect[0] != FSDM_NIL_INDEX) {
  4973.         if (Disk_BlockWrite(partFID, headerPtr,
  4974.                 newFDPtr->indirect[0] / FS_FRAGMENTS_PER_BLOCK,
  4975.                 1, (Address)indirectBlock) != 0) {
  4976.             fprintf(stderr, "Couldn't write indirect block\n");
  4977.             exit(1);
  4978.         }
  4979.         }
  4980.         close(fd);
  4981.     } else if (statBuf.st_mode & S_GFDIR) {
  4982.         char    newPath[FS_MAX_NAME_LENGTH];
  4983.  
  4984.         /*
  4985.          * Increment the current directories link count because once
  4986.          * the child gets created it will point to the parent.
  4987.          */
  4988.         dirFDPtr->numLinks++;
  4989.         /*
  4990.          * Allocate the currently free file descriptor to this directory.
  4991.          */
  4992.         InitDesc(newFDPtr, FS_DIRECTORY, FS_BLOCK_SIZE, -1, -1, -1, 
  4993.              0, 0, (int) statBuf.st_mode & 07777, statBuf.st_mtime);
  4994.         /*
  4995.          * Give the directory one full block.  The directory will
  4996.          * be initialized by CopyTree when we call it recursively.
  4997.          */
  4998.         newFDPtr->direct[0] = freeBlockNum * FS_FRAGMENTS_PER_BLOCK;
  4999.         MarkDataBitmap(headerPtr, cylBitmapPtr, freeBlockNum,
  5000.                FS_FRAGMENTS_PER_BLOCK);
  5001.         freeBlockNum++;
  5002.         sprintf(newPath, "%s%s/", path, fileName);
  5003.         printf("Directory: %s\n", newPath);
  5004.         CopyTree(partFID, fileName, newFDNum, newFDPtr, dirFDNum, TRUE, 
  5005.         newPath);
  5006.     } else {
  5007.         fprintf(stderr, "WARNING: %s%s is not a file or directory\n",
  5008.         pathName, fileName);
  5009.         freeFDNum--;
  5010.         summaryPtr->numFreeFileDesc++;
  5011.         continue;
  5012.     }
  5013.     WriteFileDesc(partFID, headerPtr, newFDNum, newFDPtr);
  5014.  
  5015.     }
  5016.  
  5017.     CloseDir(partFID, headerPtr, !printOnly, &indexInfo);
  5018.  
  5019.     if (chdir(pathName) < 0) {
  5020.     perror(pathName);
  5021.     exit(1);
  5022.     }
  5023.     closedir(unixDirPtr);
  5024.     return;
  5025. }
  5026.  
  5027. d470 6
  5028. a475 6
  5029. ReturnStatus
  5030. SetDomainHeader(labelPtr, headerPtr, spriteID, partition)
  5031.     Disk_Label        *labelPtr;    /* The disk label. */
  5032.     Fsdm_DomainHeader     *headerPtr;    /* Domain header to fill in */
  5033.     int         spriteID;    /* Host ID of machine with the disks */
  5034.     int         partition;    /* Index of partition to format */
  5035. d480 2
  5036. a481 7
  5037.     headerPtr->firstCylinder = labelPtr->partitions[partition].firstCylinder;
  5038.     headerPtr->numCylinders = labelPtr->partitions[partition].numCylinders;
  5039.     if (headerPtr->numCylinders <= 0) {
  5040.     fprintf(stderr, "Invalid partition size: %d cylinders.\n", 
  5041.         headerPtr->numCylinders);
  5042.     return FAILURE;
  5043.     }
  5044. d498 1
  5045. a498 1
  5046.     SetSCSIDiskGeometry(labelPtr, geoPtr);
  5047. d500 1
  5048. a500 1
  5049.     SetDiskGeometry(labelPtr, geoPtr);
  5050. d503 1
  5051. a503 2
  5052.     SetDomainParts(labelPtr, partition, headerPtr);
  5053.     return SUCCESS;
  5054. d525 3
  5055. a527 3
  5056. SetSCSIDiskGeometry(labelPtr, geoPtr)
  5057.     register Disk_Label        *labelPtr;    /* The disk label. */
  5058.     register Fsdm_Geometry     *geoPtr;    /* Fancy geometry information */
  5059. d532 2
  5060. a533 2
  5061.     geoPtr->numHeads = labelPtr->numHeads;
  5062.     geoPtr->sectorsPerTrack = labelPtr->numSectors;
  5063. d577 3
  5064. a579 3
  5065. SetDiskGeometry(labelPtr, geoPtr)
  5066.     register Disk_Label        *labelPtr;    /* The disk label. */
  5067.     register Fsdm_Geometry     *geoPtr;    /* Fancy geometry information */
  5068. d592 2
  5069. a593 2
  5070.     geoPtr->numHeads = labelPtr->numHeads;
  5071.     geoPtr->sectorsPerTrack = labelPtr->numSectors;
  5072. d764 2
  5073. a765 3
  5074. SetDomainParts(labelPtr, partition, headerPtr)
  5075.     register Disk_Label        *labelPtr;    /* The disk label. */
  5076.     int partition;
  5077. a776 2
  5078.     int maxSector;
  5079.     int numCylinders;
  5080. a782 7
  5081.     maxSector = labelPtr->labelSector;
  5082.     maxSector = Max(maxSector,labelPtr->bootSector + labelPtr->numBootSectors);
  5083.     maxSector = Max(maxSector,labelPtr->summarySector
  5084.     + labelPtr->numSummarySectors);
  5085.     maxSector = Max(maxSector,labelPtr->domainSector
  5086.     + labelPtr->numDomainSectors);
  5087.     numCylinders = labelPtr->partitions[partition].numCylinders;
  5088. d788 5
  5089. a792 2
  5090.     cylinders = maxSector / (geoPtr->sectorsPerTrack * geoPtr->numHeads);
  5091.     if ((maxSector % (geoPtr->sectorsPerTrack * geoPtr->numHeads)) != 0) {
  5092. d796 2
  5093. a797 1
  5094.     numBlocks = geoPtr->blocksPerCylinder * numCylinders - reservedBlocks;
  5095. d803 5
  5096. a807 3
  5097.     sets = maxSector / (geoPtr->tracksPerRotSet * geoPtr->sectorsPerTrack);
  5098.     if ((maxSector % (geoPtr->tracksPerRotSet * geoPtr->sectorsPerTrack)) 
  5099.     != 0) {
  5100. d811 2
  5101. a812 1
  5102.     numBlocks = geoPtr->blocksPerCylinder * numCylinders - reservedBlocks;
  5103. d890 2
  5104. a891 1
  5105.  *    Initialize the summary information for the domain.  
  5106. d902 2
  5107. a903 1
  5108. SetSummaryInfo(headerPtr, summaryPtr)
  5109. d905 1
  5110. a905 1
  5111.     Fsdm_SummaryInfo *summaryPtr;    /* Summary info to fill in */
  5112. d908 1
  5113. a908 1
  5114.     bzero((Address)summaryPtr, sizeof(Fsdm_SummaryInfo));
  5115. d912 2
  5116. a913 2
  5117.      * 20 KB is already allocated, 4 for the root directory,
  5118.      * 8 for lost+found, and 8 for .fscheck.out
  5119. d916 4
  5120. a919 1
  5121.                 - 20;
  5122. d921 2
  5123. a922 2
  5124.      * 5 file descriptors are already used, 0 and 1 are reserved,
  5125.      * 2 is for the root, 3 is for lost+found, and 4 is for .fscheck.out
  5126. d924 7
  5127. a930 1
  5128.     summaryPtr->numFreeFileDesc = headerPtr->numFileDesc - 5;
  5129. d955 1
  5130. a955 1
  5131.  * WriteAllFileDescs --
  5132. d957 1
  5133. a957 1
  5134.  *    Write out all of the file descriptors to disk.
  5135. d960 1
  5136. a960 1
  5137.  *    SUCCESS if the descriptors were written, FAILURE otherwise.
  5138. d968 2
  5139. a969 1
  5140. WriteAllFileDescs(partFID, headerPtr)
  5141. a970 1
  5142.     register Fsdm_DomainHeader *headerPtr;
  5143. d974 1
  5144. a974 1
  5145.     char block[FS_BLOCK_SIZE];
  5146. a976 1
  5147.     int j;
  5148. a982 1
  5149.         printf("Couldn't write bitmap\n");
  5150. d988 3
  5151. a990 2
  5152.      * canned file descriptors for the root, bad block file, the
  5153.      * lost and found directory and fscheck's output file.  
  5154. d992 1
  5155. d1003 1
  5156. a1003 2
  5157.         InitDesc(fileDescPtr, FS_FILE, 0, -1, -1, -1, 0, 0, 0, 
  5158.         curTime.tv_sec);
  5159. d1005 1
  5160. a1005 6
  5161.         InitDesc(fileDescPtr, FS_DIRECTORY, FS_BLOCK_SIZE, -1, -1, -1, 0,
  5162.             0, 0755, curTime.tv_sec);
  5163.         /*
  5164.          * Place the data in the first file system block.
  5165.          */
  5166.         fileDescPtr->direct[0] = 0;
  5167. d1007 5
  5168. a1011 13
  5169.         InitDesc(fileDescPtr, FS_DIRECTORY, 2 * FS_BLOCK_SIZE,-1, -1, -1, 0,
  5170.             0, 0755, curTime.tv_sec);
  5171.         for (j = 0; j < FSDM_NUM_LOST_FOUND_BLOCKS ; j++) {
  5172.         fileDescPtr->direct[j] = FS_FRAGMENTS_PER_BLOCK 
  5173.             * (j + 1);
  5174.         }
  5175.     } else if (index == FSDM_LOST_FOUND_FILE_NUMBER+1) {
  5176.         InitDesc(fileDescPtr, FS_FILE, 2 * FS_BLOCK_SIZE, -1, -1, -1, 0,
  5177.             0, 0755, curTime.tv_sec);
  5178.         for (j = 0; j < 2 ; j++) {
  5179.         fileDescPtr->direct[j] = FS_FRAGMENTS_PER_BLOCK 
  5180.             * (j + 1 + FSDM_NUM_LOST_FOUND_BLOCKS);
  5181.         }
  5182. d1060 303
  5183. d1390 1
  5184. a1390 1
  5185.      * Reserve file descriptors 0, 1, 2, 3, and 4. File number 0 is not used at 
  5186. d1392 1
  5187. a1392 1
  5188.      * File number 2 (FSDM_ROOT_FILE_NUMBER) is the domain's root directory.
  5189. a1394 1
  5190.      * File number 4 is for fscheck's output.
  5191. d1398 14
  5192. a1411 2
  5193.     bitmap[0] |= 0xf8;
  5194.     freeFDNum = 5;
  5195. d1446 2
  5196. a1447 2
  5197.  *    first 4K is allocated to the root directory, 8K is
  5198.  *    allocated to lost and found, and 8K to .fscheck.out.
  5199. d1458 2
  5200. a1459 1
  5201. WriteBitmap(partFID, headerPtr)
  5202. a1460 1
  5203.     register Fsdm_DomainHeader *headerPtr;
  5204. d1468 2
  5205. a1469 3
  5206.      * Set the bits corresponding to the 4K used for the root directory,
  5207.      * the 8K reserved for lost and found, and the 8K reserved for
  5208.      * .fscheck.out.
  5209. d1476 5
  5210. a1480 3
  5211.     bitmap[1] |= 0xff;
  5212.     bitmap[2] |= 0xf0;
  5213.     freeBlockNum = 5;
  5214. d1507 3
  5215. a1509 4
  5216. WriteRootDirectory(partFID, headerPtr, fdPtr)
  5217.     int             partFID;    /* Raw disk handle. */
  5218.     register Fsdm_DomainHeader     *headerPtr;    /* Domain header. */
  5219.     Fsdm_FileDescriptor        *fdPtr;        /* Root file desc */
  5220. d1511 80
  5221. a1590 5
  5222.     ReturnStatus     status;
  5223.     char         block[FS_BLOCK_SIZE];
  5224.     Fslcl_DirEntry     *dirEntryPtr;
  5225.     int         i;
  5226.     DirIndexInfo    indexInfo;
  5227. a1591 1
  5228.     CreateDir(block, 1, FSDM_ROOT_FILE_NUMBER, FSDM_ROOT_FILE_NUMBER);
  5229. a1592 1
  5230.     int offset;
  5231. d1595 10
  5232. a1604 1
  5233.     for (i = 0; i < 4; i++) {
  5234. d1607 2
  5235. d1610 2
  5236. d1613 1
  5237. d1615 7
  5238. a1621 25
  5239.     status = Disk_BlockWrite(partFID, headerPtr, headerPtr->dataOffset,
  5240.         1, block);
  5241.     if (status != 0) {
  5242.         fprintf(stderr, "WriteRootDirectory: Couldn't write directory\n");
  5243.     }
  5244.     }
  5245.     status = OpenDir(partFID, headerPtr, fdPtr, &indexInfo, &dirEntryPtr);
  5246.     if (status != SUCCESS) {
  5247.     fprintf(stderr, "Can't open root file descriptor\n");
  5248.     return status;
  5249.     }
  5250.     status = AddToDirectory(partFID, headerPtr, !printOnly, &indexInfo, 
  5251.             &dirEntryPtr, FSDM_LOST_FOUND_FILE_NUMBER, 
  5252.             "lost+found");
  5253.     if (status != SUCCESS) {
  5254.     fprintf(stderr, "Can't add lost+found to root directory.\n");
  5255.     return status;
  5256.     }
  5257.     fdPtr->numLinks++;
  5258.     status = AddToDirectory(partFID, headerPtr, !printOnly, &indexInfo,
  5259.             &dirEntryPtr, FSDM_LOST_FOUND_FILE_NUMBER + 1, 
  5260.             ".fscheck.out");
  5261.     if (status != SUCCESS) {
  5262.     fprintf(stderr, "Can't add .fscheck.out to root directory.\n");
  5263.     return status;
  5264. a1622 1
  5265.     CloseDir(partFID, headerPtr, !printOnly, &indexInfo);
  5266. d1642 2
  5267. a1643 1
  5268. WriteLostFoundDirectory(partFID, headerPtr)
  5269. a1644 1
  5270.     register Fsdm_DomainHeader *headerPtr;
  5271. d1646 7
  5272. a1652 410
  5273.     ReturnStatus     status = SUCCESS;
  5274.     char         block[FSDM_NUM_LOST_FOUND_BLOCKS * FS_BLOCK_SIZE];
  5275.     Fslcl_DirEntry     *dirEntryPtr;
  5276.     int         i;
  5277.  
  5278.     CreateDir(block, FSDM_NUM_LOST_FOUND_BLOCKS, FSDM_LOST_FOUND_FILE_NUMBER, 
  5279.     FSDM_ROOT_FILE_NUMBER);
  5280.     if (printOnly) {
  5281.     int offset;
  5282.     printf("lost+found Directory\n");
  5283.     offset = 0;
  5284.     for (i = 0; i < 4; i++) {
  5285.         dirEntryPtr = (Fslcl_DirEntry *)((int)block + offset);
  5286.         Disk_PrintDirEntry(dirEntryPtr);
  5287.         offset += dirEntryPtr->recordLength;
  5288.     }
  5289.     } else {
  5290.     status = Disk_BlockWrite(partFID, headerPtr, headerPtr->dataOffset + 1,
  5291.             FSDM_NUM_LOST_FOUND_BLOCKS, block);
  5292.     if (status != 0) {
  5293.         fprintf(stderr, 
  5294.         "WriteLostFoundDirectory: Couldn't write directory\n");
  5295.     }
  5296.     }
  5297.     return(status);
  5298. }
  5299.  
  5300. /*
  5301.  *----------------------------------------------------------------------
  5302.  *
  5303.  * InitDesc --
  5304.  *
  5305.  *    Set up a file descriptor as allocated.
  5306.  *
  5307.  * Results:
  5308.  *    None.
  5309.  *
  5310.  * Side effects:
  5311.  *    File descriptor fields filled in.
  5312.  *
  5313.  *----------------------------------------------------------------------
  5314.  */
  5315. void
  5316. InitDesc(fileDescPtr, fileType, numBytes, devServer, devType, devUnit, uid,
  5317.     gid, permissions, time)
  5318.     Fsdm_FileDescriptor    *fileDescPtr;
  5319.     int            fileType;
  5320.     int            numBytes;
  5321.     int            devServer;
  5322.     int            devType;
  5323.     int            devUnit;
  5324.     int            uid;
  5325.     int            gid;
  5326.     int            permissions;
  5327.     long        time;
  5328. {
  5329.     int        index;
  5330.  
  5331.     fileDescPtr->flags = FSDM_FD_ALLOC;
  5332.     fileDescPtr->fileType = fileType;
  5333.     fileDescPtr->permissions = permissions;
  5334.     fileDescPtr->uid = uid;
  5335.     fileDescPtr->gid = gid;
  5336.     fileDescPtr->lastByte = numBytes - 1;
  5337.     fileDescPtr->firstByte = -1;
  5338.     if (fileType == FS_DIRECTORY) {
  5339.     fileDescPtr->numLinks = 2;
  5340.     } else {
  5341.     fileDescPtr->numLinks = 1;
  5342.     }
  5343.     fileDescPtr->devServerID = devServer;
  5344.     fileDescPtr->devType = devType;
  5345.     fileDescPtr->devUnit = devUnit;
  5346.  
  5347.     /*
  5348.      * Set the time stamps.  This assumes that universal time,
  5349.      * not local time, is used for time stamps.
  5350.      */
  5351.     fileDescPtr->createTime = (int) time;
  5352.     fileDescPtr->accessTime = (int) time;
  5353.     fileDescPtr->descModifyTime = (int) time;
  5354.     fileDescPtr->dataModifyTime = (int) time;
  5355.  
  5356.     /*
  5357.      * Place the data in the first filesystem block.
  5358.      */
  5359.     for (index = 0; index < FSDM_NUM_DIRECT_BLOCKS ; index++) {
  5360.     fileDescPtr->direct[index] = FSDM_NIL_INDEX;
  5361.     }
  5362.     for (index = 0; index < FSDM_NUM_INDIRECT_BLOCKS ; index++) {
  5363.     fileDescPtr->indirect[index] = FSDM_NIL_INDEX;
  5364.     }
  5365.     if (numBytes > 0) {
  5366.     int    numBlocks;
  5367.  
  5368.     numBlocks = (numBytes - 1) / FS_BLOCK_SIZE + 1;
  5369.     if (numBlocks > FSDM_NUM_DIRECT_BLOCKS) {
  5370.         fileDescPtr->numKbytes = (numBlocks + 1) * (FS_BLOCK_SIZE / 1024);
  5371.     } else {
  5372.         fileDescPtr->numKbytes = (numBytes + 1023) / 1024;
  5373.     }
  5374.     } else {
  5375.     fileDescPtr->numKbytes = 0;
  5376.     }
  5377.  
  5378.     fileDescPtr->version = 1;
  5379. }
  5380.  
  5381. /*
  5382.  *----------------------------------------------------------------------
  5383.  *
  5384.  * AddToDirectory --
  5385.  *
  5386.  *    Add the file descriptor to a directory.  
  5387.  *
  5388.  * Results:
  5389.  *    SUCCESS if the desciptor was added ok, FAILURE otherwise
  5390.  *
  5391.  * Side effects:
  5392.  *    The directory is modified to contain the file.
  5393.  *
  5394.  *----------------------------------------------------------------------
  5395.  */
  5396. ReturnStatus
  5397. AddToDirectory(fid, headerPtr, writeDisk, dirIndexPtr, dirEntryPtrPtr, 
  5398.     fileNumber, fileName)
  5399.     int            fid;        /* Handle on raw disk. */
  5400.     Fsdm_DomainHeader     *headerPtr;    /* Domain header. */
  5401.     Boolean        writeDisk;    /* Write the disk? */
  5402.     DirIndexInfo    *dirIndexPtr;    /* Index information. */
  5403.     Fslcl_DirEntry    **dirEntryPtrPtr; /* Directory entry. */
  5404.     int             fileNumber;    /* File number to add. */
  5405.     char         *fileName;    /* Name of file to add. */
  5406. {
  5407.     int             nameLength;
  5408.     int             recordLength;
  5409.     int             leftOver;
  5410.     int            oldRecLength;
  5411.     Fslcl_DirEntry    *dirEntryPtr;
  5412.     ReturnStatus     status = SUCCESS;
  5413.  
  5414.     dirEntryPtr = *dirEntryPtrPtr;
  5415.  
  5416.     nameLength = strlen(fileName);
  5417.     recordLength = Fslcl_DirRecLength(nameLength);
  5418.  
  5419.     while (1) {
  5420.     if (dirEntryPtr->fileNumber != 0) {
  5421.         oldRecLength = Fslcl_DirRecLength(dirEntryPtr->nameLength);
  5422.         leftOver = dirEntryPtr->recordLength - oldRecLength;
  5423.         if (leftOver >= recordLength) {
  5424.         dirEntryPtr->recordLength = oldRecLength;
  5425.         dirEntryPtr = 
  5426.             (Fslcl_DirEntry *) ((int) dirEntryPtr + oldRecLength);
  5427.         dirEntryPtr->recordLength = leftOver;
  5428.         dirIndexPtr->dirOffset += oldRecLength;
  5429.         } else {
  5430.         status = NextDirEntry(fid, headerPtr, writeDisk,
  5431.                 dirIndexPtr, &dirEntryPtr);
  5432.         if (status != SUCCESS) {
  5433.             fprintf(stderr, "Can't add to directory\n");
  5434.             return status;
  5435.         }
  5436.         continue;
  5437.         }
  5438.     } else if (dirEntryPtr->recordLength < recordLength) {
  5439.         status = NextDirEntry(fid, headerPtr, writeDisk,
  5440.             dirIndexPtr, &dirEntryPtr);
  5441.         if (status != SUCCESS) {
  5442.         fprintf(stderr, "Can't add to directory\n");
  5443.         return status;
  5444.         }
  5445.         continue;
  5446.     }
  5447.     dirEntryPtr->fileNumber = fileNumber;
  5448.     dirEntryPtr->nameLength = nameLength;
  5449.     (void)strcpy(dirEntryPtr->fileName, fileName);
  5450.     leftOver = dirEntryPtr->recordLength - recordLength;
  5451.     if (leftOver > FSLCL_DIR_ENTRY_HEADER) {
  5452.         dirEntryPtr->recordLength = recordLength;
  5453.         dirEntryPtr =(Fslcl_DirEntry *) ((int) dirEntryPtr + recordLength);
  5454.         dirEntryPtr->fileNumber = 0;
  5455.         dirEntryPtr->recordLength = leftOver;
  5456.         dirIndexPtr->dirOffset += recordLength;
  5457.     } else {
  5458.         status = NextDirEntry(fid, headerPtr, writeDisk, 
  5459.                 dirIndexPtr, &dirEntryPtr);
  5460.         if (status != SUCCESS) {
  5461.         fprintf(stderr, "Can't add to directory\n");
  5462.         return status;
  5463.         }
  5464.     }
  5465.     *dirEntryPtrPtr = dirEntryPtr;
  5466.     return status;
  5467.     }
  5468. }
  5469.  
  5470. /*
  5471.  *----------------------------------------------------------------------
  5472.  *
  5473.  * OpenDir --
  5474.  *
  5475.  *    Set up the structure to allow moving through the given directory.
  5476.  *
  5477.  * Results:
  5478.  *    SUCCESS if the open was successful, FAILURE otherwise
  5479.  *
  5480.  * Side effects:
  5481.  *    The index structure is set up and *dirEntryPtrPtr set to point to
  5482.  *    the first directory entry.
  5483.  *
  5484.  *----------------------------------------------------------------------
  5485.  */
  5486. ReturnStatus
  5487. OpenDir(fid, headerPtr, fdPtr, indexInfoPtr, dirEntryPtrPtr)
  5488.     int            fid;        /* Handle on raw disk. */
  5489.     Fsdm_DomainHeader     *headerPtr;    /* Domain header. */
  5490.     Fsdm_FileDescriptor    *fdPtr;        /* The file descriptor for the
  5491.                      * directory. */
  5492.     DirIndexInfo     *indexInfoPtr;    /* Index info struct */
  5493.     Fslcl_DirEntry    **dirEntryPtrPtr; /* Current directory entry */
  5494. {
  5495.  
  5496.     *dirEntryPtrPtr = NULL;
  5497.     if (fdPtr->lastByte == -1) {
  5498.     /*
  5499.      * Empty directory.
  5500.      */
  5501.     return SUCCESS;
  5502.     } else if ((fdPtr->lastByte + 1) % FSLCL_DIR_BLOCK_SIZE != 0) {
  5503.     fprintf(stderr, "Directory not multiple of directory block size.\n");
  5504.     return FAILURE;
  5505.     } else if (fdPtr->fileType != FS_DIRECTORY) {
  5506.     fprintf(stderr, "OpenDir: Not a directory\n");
  5507.     return FAILURE;
  5508.     }
  5509.  
  5510.     /*
  5511.      * Initialize the index structure.
  5512.      */
  5513.     indexInfoPtr->fdPtr = fdPtr;
  5514.     indexInfoPtr->blockNum = 0;
  5515.     indexInfoPtr->blockAddr = fdPtr->direct[0] / FS_FRAGMENTS_PER_BLOCK + 
  5516.                   headerPtr->dataOffset;
  5517.     /*
  5518.      * Read in the directory block.
  5519.      */
  5520.     if (fdPtr->lastByte != FS_BLOCK_SIZE - 1) {
  5521.     fprintf(stderr, "We created a directory that's not 4K?\n");
  5522.     return FAILURE;
  5523.     }
  5524.     if (Disk_BlockRead(fid, headerPtr,
  5525.                indexInfoPtr->blockAddr,
  5526.                1, indexInfoPtr->dirBlock) < 0) {
  5527.     fprintf(stderr, "OpenDir: Read failed block %d\n",
  5528.             indexInfoPtr->blockAddr);
  5529.     return FAILURE;
  5530.     } 
  5531.     indexInfoPtr->dirOffset = 0;
  5532.     *dirEntryPtrPtr = (Fslcl_DirEntry *) indexInfoPtr->dirBlock;
  5533.     return SUCCESS;
  5534. }
  5535.  
  5536.  
  5537. /*
  5538.  *----------------------------------------------------------------------
  5539.  *
  5540.  * NextDirEntry --
  5541.  *
  5542.  *    Get a pointer to the next directory entry.
  5543.  *
  5544.  * Results:
  5545.  *    SUCCESS if the next entry was found ok, FAILURE otherwise
  5546.  *
  5547.  * Side effects:
  5548.  *    The index structure is modified and *dirEntryPtrPtr set to point
  5549.  *    to the next directory entry.
  5550.  *
  5551.  *----------------------------------------------------------------------
  5552.  */
  5553. ReturnStatus
  5554. NextDirEntry(fid, headerPtr, writeDisk, indexInfoPtr, dirEntryPtrPtr)
  5555.     int            fid;        /* Handle on raw disk. */
  5556.     Fsdm_DomainHeader     *headerPtr;    /* Domain header. */
  5557.     Boolean        writeDisk;    /* Write the disk? */
  5558.     DirIndexInfo     *indexInfoPtr;    /* Index information. */
  5559.     Fslcl_DirEntry    **dirEntryPtrPtr; /* Current directory entry */
  5560. {
  5561.     Fslcl_DirEntry    *dirEntryPtr;    
  5562.  
  5563.     dirEntryPtr = *dirEntryPtrPtr;
  5564.     indexInfoPtr->dirOffset += dirEntryPtr->recordLength;
  5565.     if (indexInfoPtr->dirOffset < FS_BLOCK_SIZE) {
  5566.     /*
  5567.      * The next directory entry is in the current block.
  5568.      */
  5569.     *dirEntryPtrPtr = (Fslcl_DirEntry *)
  5570.             &(indexInfoPtr->dirBlock[indexInfoPtr->dirOffset]);
  5571.     return SUCCESS;
  5572.     } else {
  5573.     Fsdm_FileDescriptor    *fdPtr;
  5574.     int            i;
  5575.  
  5576.     printf("Adding new block to directory ...\n");
  5577.  
  5578.     /*
  5579.      * Write out the current block and set up the next one.
  5580.      */
  5581.     if (writeDisk) {
  5582.         if (Disk_BlockWrite(fid, headerPtr, indexInfoPtr->blockAddr,
  5583.                 1, indexInfoPtr->dirBlock) < 0) {
  5584.         fprintf(stderr, "NextDirEntry: Write failed block %d\n",
  5585.                 indexInfoPtr->blockAddr);
  5586.         return FAILURE;
  5587.         }
  5588.     }
  5589.     fdPtr = indexInfoPtr->fdPtr;
  5590.     fdPtr->lastByte += FS_BLOCK_SIZE;
  5591.     fdPtr->numKbytes += FS_FRAGMENTS_PER_BLOCK;
  5592.     indexInfoPtr->blockNum++;
  5593.     fdPtr->direct[indexInfoPtr->blockNum] = 
  5594.                 freeBlockNum * FS_FRAGMENTS_PER_BLOCK;
  5595.     MarkDataBitmap(headerPtr, cylBitmapPtr, freeBlockNum,
  5596.                FS_FRAGMENTS_PER_BLOCK);
  5597.     indexInfoPtr->blockAddr = freeBlockNum + headerPtr->dataOffset;
  5598.     freeBlockNum++;
  5599.     for (i = 0, dirEntryPtr = (Fslcl_DirEntry *)indexInfoPtr->dirBlock; 
  5600.          i < FS_BLOCK_SIZE / FSLCL_DIR_BLOCK_SIZE;
  5601.      i++,dirEntryPtr=(Fslcl_DirEntry *)((unsigned)dirEntryPtr+FSLCL_DIR_BLOCK_SIZE)) {
  5602.         dirEntryPtr->fileNumber = 0;
  5603.         dirEntryPtr->recordLength = FSLCL_DIR_BLOCK_SIZE;
  5604.         dirEntryPtr->nameLength = 0;
  5605.     }
  5606.     indexInfoPtr->dirOffset = 0;
  5607.     *dirEntryPtrPtr = (Fslcl_DirEntry *) indexInfoPtr->dirBlock;
  5608.     return SUCCESS;
  5609.     }
  5610. }
  5611.  
  5612.  
  5613. /*
  5614.  *----------------------------------------------------------------------
  5615.  *
  5616.  * CloseDir --
  5617.  *
  5618.  *    Flushes the current directory block to disk, if necessary.
  5619.  *
  5620.  * Results:
  5621.  *    SUCCESS if the directory was closed ok, FAILURE otherwise
  5622.  *
  5623.  * Side effects:
  5624.  *    Stuff is written to disk.
  5625.  *
  5626.  *----------------------------------------------------------------------
  5627.  */
  5628. ReturnStatus
  5629. CloseDir(fid, headerPtr, writeDisk, indexInfoPtr)
  5630.     int            fid;        /* Handle on raw disk. */
  5631.     Fsdm_DomainHeader     *headerPtr;    /* Domain header. */
  5632.     Boolean        writeDisk;    /* Write the disk? */
  5633.     DirIndexInfo     *indexInfoPtr;    /* Index information. */
  5634. {
  5635.  
  5636.     if (writeDisk) {
  5637.     if (Disk_BlockWrite(fid, headerPtr, indexInfoPtr->blockAddr,
  5638.                 1, indexInfoPtr->dirBlock) < 0) {
  5639.         fprintf(stderr, "CloseDir: Write (2) failed block %d\n",
  5640.                 indexInfoPtr->blockAddr);
  5641.         return FAILURE;
  5642.     }
  5643.     }
  5644.     return SUCCESS;
  5645. }
  5646.  
  5647. /*
  5648.  *----------------------------------------------------------------------
  5649.  *
  5650.  * ReadFileDesc --
  5651.  *
  5652.  *    Return the given file descriptor.
  5653.  *
  5654.  * Results:
  5655.  *    SUCCESS if file descriptor was read ok, FAILURE otherwise
  5656.  *
  5657.  * Side effects:
  5658.  *    The file descriptor struct is filled in.
  5659.  *
  5660.  *----------------------------------------------------------------------
  5661.  */
  5662. ReturnStatus
  5663. ReadFileDesc(fid, headerPtr, fdNum, fdPtr)
  5664.     int            fid;        /* Handle on raw disk. */
  5665.     Fsdm_DomainHeader     *headerPtr;    /* Domain header. */
  5666.     int            fdNum;        /* File number. */
  5667.     Fsdm_FileDescriptor    *fdPtr;        /* Place to store fd. */
  5668. {
  5669.     static char        block[FS_BLOCK_SIZE];
  5670.     int            blockNum;
  5671.     int            offset;
  5672.  
  5673.     blockNum = headerPtr->fileDescOffset + fdNum / FSDM_FILE_DESC_PER_BLOCK;
  5674.     offset = (fdNum & (FSDM_FILE_DESC_PER_BLOCK - 1)) * FSDM_MAX_FILE_DESC_SIZE;
  5675.     if (Disk_BlockRead(fid, headerPtr, blockNum, 1, 
  5676.                (Address) block) < 0) {
  5677.     fprintf(stderr, "ReadFileDesc: Read failed\n");
  5678.     return FAILURE;
  5679.     }
  5680.     bcopy((Address)&block[offset], (Address)fdPtr, sizeof(Fsdm_FileDescriptor));
  5681.     return SUCCESS;
  5682. }
  5683. d1654 2
  5684. a1655 69
  5685.  
  5686. /*
  5687.  *----------------------------------------------------------------------
  5688.  *
  5689.  * WriteFileDesc --
  5690.  *
  5691.  *    Write the given file descriptor.
  5692.  *
  5693.  * Results:
  5694.  *    SUCCESS if the write was successful, FAILURE otherwise
  5695.  *
  5696.  * Side effects:
  5697.  *    Stuff is written to disk.
  5698.  *
  5699.  *----------------------------------------------------------------------
  5700.  */
  5701. ReturnStatus
  5702. WriteFileDesc(fid, headerPtr, fdNum, fdPtr)
  5703.     int            fid;        /* Handle on raw disk. */
  5704.     Fsdm_DomainHeader     *headerPtr;    /* Domain header. */
  5705.     int            fdNum;        /* File number. */
  5706.     Fsdm_FileDescriptor    *fdPtr;        /* Place to store fd. */
  5707. {
  5708.     static char        block[FS_BLOCK_SIZE];
  5709.     int            blockNum;
  5710.     int            offset;
  5711.  
  5712.     blockNum = headerPtr->fileDescOffset + fdNum / FSDM_FILE_DESC_PER_BLOCK;
  5713.     offset = (fdNum & (FSDM_FILE_DESC_PER_BLOCK - 1)) * FSDM_MAX_FILE_DESC_SIZE;
  5714.     if (Disk_BlockRead(fid, headerPtr, blockNum, 1, 
  5715.                (Address) block) < 0) {
  5716.     fprintf(stderr, "WriteFileDesc: Read failed\n");
  5717.     return FAILURE;
  5718.     }
  5719.     bcopy((Address)fdPtr, (Address)&block[offset], sizeof(Fsdm_FileDescriptor));
  5720.     if (Disk_BlockWrite(fid, headerPtr, blockNum, 1, 
  5721.                (Address) block) < 0) {
  5722.     fprintf(stderr, "WriteFileDesc: Write failed\n");
  5723.     return FAILURE;
  5724.     }
  5725.     return SUCCESS;
  5726. }
  5727. /*
  5728.  *----------------------------------------------------------------------
  5729.  *
  5730.  * CreateDir --
  5731.  *
  5732.  *    Create a directory out of file system blocks.
  5733.  *
  5734.  * Results:
  5735.  *    None.
  5736.  *
  5737.  * Side effects:
  5738.  *    File system block set up as a directory.
  5739.  *
  5740.  *----------------------------------------------------------------------
  5741.  */
  5742. void
  5743. CreateDir(blocks, numBlocks, dot, dotDot)
  5744.     Address    blocks;        /* Blocks to create directory in. */
  5745.     int        numBlocks;    /* Number of blocks. */
  5746.     int        dot;        /* File number of directory. */
  5747.     int        dotDot;        /* File number of parent. */
  5748. {
  5749.     Fslcl_DirEntry    *dirEntryPtr;
  5750.     char    *fileName;
  5751.     int        offset;
  5752.     int        length;
  5753.     int        i;
  5754. a1656 1
  5755.     dirEntryPtr = (Fslcl_DirEntry *)blocks;
  5756. d1659 1
  5757. a1659 1
  5758.     dirEntryPtr->fileNumber = dot;
  5759. d1665 1
  5760. a1665 1
  5761.     dirEntryPtr = (Fslcl_DirEntry *)((int)blocks + offset);
  5762. d1668 1
  5763. a1668 1
  5764.     dirEntryPtr->fileNumber = dotDot;
  5765. d1672 1
  5766. d1676 3
  5767. a1678 2
  5768.     for (dirEntryPtr = (Fslcl_DirEntry *)&blocks[FSLCL_DIR_BLOCK_SIZE], i = 1; 
  5769.      i < (FS_BLOCK_SIZE * numBlocks) / FSLCL_DIR_BLOCK_SIZE;
  5770. d1684 9
  5771. a1692 31
  5772. }
  5773. int fragMasks[FS_FRAGMENTS_PER_BLOCK + 1] = {0x0, 0x08, 0x0c, 0x0e, 0x0f};
  5774.  
  5775.  
  5776. /*
  5777.  *----------------------------------------------------------------------
  5778.  *
  5779.  * MarkDataBitmap --
  5780.  *
  5781.  *    Mark the appropriate bits in the data block bitmap.
  5782.  *
  5783.  * Results:
  5784.  *    None.
  5785.  *
  5786.  * Side effects:
  5787.  *    Data block marked.
  5788.  *
  5789.  *----------------------------------------------------------------------
  5790.  */
  5791. void
  5792. MarkDataBitmap(headerPtr, cylBitmapPtr, blockNum, numFrags)
  5793.     Fsdm_DomainHeader    *headerPtr;
  5794.     unsigned char    *cylBitmapPtr;
  5795.     int            blockNum;
  5796.     int            numFrags;
  5797. {
  5798.     unsigned char    *bitmapPtr;
  5799.  
  5800.     bitmapPtr = GetBitmapPtr(headerPtr, cylBitmapPtr, blockNum);
  5801.     if ((blockNum % headerPtr->geometry.blocksPerCylinder) & 0x1) {
  5802.     *bitmapPtr |= fragMasks[numFrags];
  5803. d1694 2
  5804. a1695 1
  5805.     *bitmapPtr |= fragMasks[numFrags] << 4;
  5806. d1697 1
  5807. a1697 95
  5808. }
  5809.  
  5810. /*
  5811.  *----------------------------------------------------------------------
  5812.  *
  5813.  * ReadFileDescBitmap --
  5814.  *
  5815.  *    Read in the file descriptor bitmap.
  5816.  *
  5817.  * Results:
  5818.  *    A pointer to the file descriptor bit map.
  5819.  *
  5820.  * Side effects:
  5821.  *    Memory allocated for the bit map.
  5822.  *
  5823.  *----------------------------------------------------------------------
  5824.  */
  5825. unsigned char *
  5826. ReadFileDescBitmap(fid, headerPtr)
  5827.     int            fid;        /* Handle on raw disk. */
  5828.     Fsdm_DomainHeader     *headerPtr;    /* Domain header. */
  5829. {
  5830.     register unsigned char *bitmap;
  5831.  
  5832.     /*
  5833.      * Allocate the bitmap.
  5834.      */
  5835.     bitmap = (unsigned char *)malloc(
  5836.     (unsigned) headerPtr->fdBitmapBlocks * FS_BLOCK_SIZE);
  5837.     if (Disk_BlockRead(fid, headerPtr, headerPtr->fdBitmapOffset,
  5838.           headerPtr->fdBitmapBlocks, (Address)bitmap) < 0) {
  5839.     fprintf(stderr, "ReadFileDescBitmap: Read failed");
  5840.     exit(1);
  5841.     }
  5842.     return(bitmap);
  5843. }
  5844.  
  5845. /*
  5846.  *----------------------------------------------------------------------
  5847.  *
  5848.  * ReadBitmap --
  5849.  *
  5850.  *    Read the bitmap off disk.
  5851.  *
  5852.  * Results:
  5853.  *    A pointer to the bitmap.
  5854.  *
  5855.  * Side effects:
  5856.  *    Memory allocated for the bit map.
  5857.  *
  5858.  *----------------------------------------------------------------------
  5859.  */
  5860. unsigned char *
  5861. ReadBitmap(fid, headerPtr)
  5862.     int            fid;        /* Handle on raw disk. */
  5863.     Fsdm_DomainHeader     *headerPtr;    /* Domain header. */
  5864. {
  5865.     unsigned char *bitmap;
  5866.  
  5867.     bitmap = (unsigned char *)malloc((unsigned) 
  5868.         headerPtr->bitmapBlocks * FS_BLOCK_SIZE);
  5869.     if (Disk_BlockRead(fid, headerPtr, headerPtr->bitmapOffset,
  5870.           headerPtr->bitmapBlocks, (Address) bitmap) < 0) {
  5871.     fprintf(stderr, "ReadBitmap: Read failed");
  5872.     exit(1);
  5873.     }
  5874.     return(bitmap);
  5875. }
  5876.  
  5877. /*
  5878.  *----------------------------------------------------------------------
  5879.  *
  5880.  * WriteFileDescBitmap --
  5881.  *
  5882.  *    Write out the file descriptor bitmap.
  5883.  *
  5884.  * Results:
  5885.  *    None.
  5886.  *
  5887.  * Side effects:
  5888.  *    None.
  5889.  *
  5890.  *----------------------------------------------------------------------
  5891.  */
  5892. void
  5893. WriteFileDescBitmap(fid, headerPtr, bitmap)
  5894.     int            fid;        /* Handle on raw disk. */
  5895.     Fsdm_DomainHeader     *headerPtr;    /* Domain header. */
  5896.     unsigned char     *bitmap;    /* Bitmap to write. */
  5897. {
  5898.     if (Disk_BlockWrite(fid, headerPtr, headerPtr->fdBitmapOffset,
  5899.            headerPtr->fdBitmapBlocks, (Address)bitmap) < 0) {
  5900.     fprintf(stderr, "WriteFileDescBitmap: Write failed");
  5901.     exit(1);
  5902.     }
  5903. a1698 1
  5904.  
  5905. @
  5906.  
  5907.  
  5908. 1.13
  5909. log
  5910. @fixed a couple of bugs in printfs
  5911. @
  5912. text
  5913. @d11 1
  5914. a11 1
  5915. static char rcsid[] = "$Header: /sprite/src/admin/fsmake/RCS/fsmake.c,v 1.12 89/08/29 17:03:06 jhh Exp Locker: jhh $ SPRITE (Berkeley)";
  5916. d167 1
  5917. a167 1
  5918.     if (bootSectors > FS_MAX_BOOT_SECTORS) {
  5919. d169 1
  5920. a169 1
  5921.         FS_MAX_BOOT_SECTORS);
  5922. d172 1
  5923. a172 1
  5924.     if ((bootSectors != -1) && (bootSectors % FS_BOOT_SECTOR_INC != 0)) {
  5925. d174 1
  5926. a174 1
  5927.         FS_BOOT_SECTOR_INC);
  5928. d215 5
  5929. a219 1
  5930.     partFID = open(partitionName, O_RDWR);
  5931. d294 3
  5932. a296 3
  5933.     FsDomainHeader     *headerPtr;
  5934.     FsSummaryInfo     *summaryPtr;
  5935.     FsSummaryInfo     *oldSummaryPtr;
  5936. d317 1
  5937. a317 1
  5938.     oldSummaryPtr = (FsSummaryInfo *) block;
  5939. d365 1
  5940. a365 1
  5941.     headerPtr = (FsDomainHeader *)
  5942. d385 1
  5943. a385 1
  5944.     summaryPtr = (FsSummaryInfo *) malloc(DEV_BYTES_PER_SECTOR);
  5945. d473 1
  5946. a473 1
  5947.     FsDomainHeader *headerPtr;    /* Reference to domain header to fill in */
  5948. d477 1
  5949. a477 1
  5950.     register FsGeometry *geoPtr;/* The layout information for the disk */
  5951. d479 1
  5952. a479 1
  5953.     headerPtr->magic = FS_DOMAIN_MAGIC;
  5954. d527 1
  5955. a527 1
  5956.     register FsGeometry *geoPtr;    /* Fancy geometry information */
  5957. a530 1
  5958.     int numRotSets;        /* Rotational sets per cylinder */
  5959. a537 1
  5960. retry:
  5961. d543 4
  5962. a546 61
  5963.     /*
  5964.      * Currently the Fs_Geometry typedef has a limit on the number
  5965.      * of blocks per rotational set.  Ideally, for a SCSI disk, we'd
  5966.      * just have one rotational set per cylinder, but we might have
  5967.      * to have several to get around this (silly) restriction.
  5968.      */
  5969.     numRotSets = blocksPerCyl / FS_MAX_ROT_POSITIONS;
  5970.     if (numRotSets < 1) {
  5971.     /*
  5972.      * Simple case.  Less than FS_MAX_ROT_POSITIONS number of blocks.
  5973.      * Make the cylinder into one rotational set.
  5974.      */
  5975.     geoPtr->rotSetsPerCyl = 1;
  5976.     geoPtr->blocksPerRotSet = blocksPerCyl;
  5977.     geoPtr->blocksPerCylinder = blocksPerCyl;
  5978.     geoPtr->tracksPerRotSet = geoPtr->numHeads;
  5979.     for (index = 0; index < blocksPerCyl; index++){
  5980.         geoPtr->blockOffset[index] = index * DISK_SECTORS_PER_BLOCK;
  5981.     }
  5982.     for (index = blocksPerCyl; index < FS_MAX_ROT_POSITIONS; index++){
  5983.         geoPtr->blockOffset[index] = -1;
  5984.     }
  5985.     } else {
  5986.     /*
  5987.      * Sigh, have to figure out a good number of tracks for
  5988.      * each rotational set.  In the worst case each track is
  5989.      * its own rotational set.
  5990.      */
  5991.     for (numRotSets += 1; numRotSets <= geoPtr->numHeads; numRotSets++) {
  5992.         if (blocksPerCyl % numRotSets == 0) {
  5993.         /*
  5994.          * Found a number of rotational sets that evenly divides
  5995.          * the total possible number of blocks in the cylinder.
  5996.          */
  5997.         goto foundNumSets;
  5998.         }
  5999.     }
  6000.     printf("No good number of rotational sets with %d blocks/cyl.\n",
  6001.         blocksPerCyl);
  6002.     blocksPerCyl--;
  6003.     if (blocksPerCyl < 1) {
  6004.         panic("Can't determine file system block layout.\n");
  6005.     }
  6006.     goto retry;
  6007.  
  6008. foundNumSets:
  6009.     printf("Using %d rotational sets, %d blocks/set, %d sectors/cyl wasted\n",
  6010.         numRotSets, blocksPerCyl / numRotSets,
  6011.         geoPtr->sectorsPerTrack * geoPtr->numHeads - 
  6012.         blocksPerCyl * DISK_SECTORS_PER_BLOCK);
  6013.     geoPtr->rotSetsPerCyl = numRotSets;
  6014.     geoPtr->blocksPerRotSet = blocksPerCyl / numRotSets;
  6015.     geoPtr->blocksPerCylinder = blocksPerCyl;
  6016.     geoPtr->tracksPerRotSet = geoPtr->numHeads / numRotSets;
  6017.     for (index = 0; index < geoPtr->blocksPerRotSet; index++){
  6018.         geoPtr->blockOffset[index] = index * DISK_SECTORS_PER_BLOCK;
  6019.     }
  6020.     for ( ; index < FS_MAX_ROT_POSITIONS; index++){
  6021.         geoPtr->blockOffset[index] = -1;
  6022.     }
  6023.     }
  6024. d550 1
  6025. a550 1
  6026.     for (index = 0 ; index < FS_MAX_ROT_POSITIONS ; index++) {
  6027. d579 1
  6028. a579 1
  6029.     register FsGeometry *geoPtr;    /* Fancy geometry information */
  6030. d712 1
  6031. a712 1
  6032.         for (index = numBlocks; index < FS_MAX_ROT_POSITIONS; index++){
  6033. d737 1
  6034. a737 1
  6035.     for (index = 0 ; index < FS_MAX_ROT_POSITIONS ; index++) {
  6036. d766 1
  6037. a766 1
  6038.     register FsDomainHeader *headerPtr;
  6039. d768 1
  6040. a768 1
  6041.     register FsGeometry *geoPtr;
  6042. a773 2
  6043.     int numSectors;        /* Sectors per rotational set */
  6044.     int numSets;        /* Number of reserved rotational sets */
  6045. d775 2
  6046. a780 1
  6047.      * It is easiest to do this by reserving one or more rotational sets.
  6048. d783 26
  6049. a808 5
  6050.     numSectors = geoPtr->tracksPerRotSet * geoPtr->sectorsPerTrack;
  6051.     for ( numSets = 1; ; numSets++ ) {
  6052.     if (numSets * numSectors >
  6053.         diskInfoPtr->domainSector + diskInfoPtr->numDomainSectors) {
  6054.         break;
  6055. d810 3
  6056. d814 1
  6057. a814 2
  6058.     printf("Reserving %d blocks for domain header, etc.\n",
  6059.             numSets*geoPtr->blocksPerRotSet);
  6060. a822 2
  6061.     numBlocks = geoPtr->blocksPerCylinder * diskInfoPtr->numCylinders -
  6062.             numSets * geoPtr->blocksPerRotSet;
  6063. d826 2
  6064. a827 2
  6065.     numFiles          &= ~(FS_FILE_DESC_PER_BLOCK-1);
  6066.     offset              = numSets * geoPtr->blocksPerRotSet;
  6067. d837 2
  6068. a838 2
  6069.     numBlocks          -= numFiles / FS_FILE_DESC_PER_BLOCK;
  6070.     offset              += numFiles / FS_FILE_DESC_PER_BLOCK;
  6071. d866 1
  6072. a866 1
  6073.         numFiles -= numBlocksNeeded * FS_FILE_DESC_PER_BLOCK;
  6074. d877 1
  6075. a877 1
  6076.         numFiles += extraBlocks * FS_FILE_DESC_PER_BLOCK;
  6077. d904 2
  6078. a905 2
  6079.     FsDomainHeader *headerPtr;    /* Domain header to summarize */
  6080.     FsSummaryInfo *summaryPtr;    /* Reference to summary info to fill in */
  6081. d969 1
  6082. a969 1
  6083.     register FsDomainHeader *headerPtr;
  6084. d975 1
  6085. a975 1
  6086.     register FsFileDescriptor *fileDescPtr;
  6087. d995 1
  6088. a995 1
  6089.          index < FS_FILE_DESC_PER_BLOCK;
  6090. d997 6
  6091. a1002 6
  6092.     fileDescPtr = (FsFileDescriptor *)((int)block +
  6093.                        index * FS_MAX_FILE_DESC_SIZE);
  6094.     fileDescPtr->magic = FS_FD_MAGIC;
  6095.     if (index < FS_BAD_BLOCK_FILE_NUMBER) {
  6096.         fileDescPtr->flags = FS_FD_RESERVED;
  6097.     } else if (index == FS_BAD_BLOCK_FILE_NUMBER) {
  6098. d1004 1
  6099. a1004 1
  6100.     } else if (index == FS_ROOT_FILE_NUMBER) {
  6101. d1006 1
  6102. a1006 1
  6103.     } else if (index == FS_LOST_FOUND_FILE_NUMBER) {
  6104. d1008 1
  6105. a1008 1
  6106.     } else if ((index == FS_LOST_FOUND_FILE_NUMBER+1) && makeFile) {
  6107. d1010 1
  6108. a1010 1
  6109.     } else if ((index == FS_LOST_FOUND_FILE_NUMBER+2) && makeFscheckOut) {
  6110. d1013 1
  6111. a1013 1
  6112.         fileDescPtr->flags = FS_FD_FREE;
  6113. d1031 1
  6114. a1031 1
  6115.          index < FS_FILE_DESC_PER_BLOCK;
  6116. d1033 4
  6117. a1036 4
  6118.         fileDescPtr = (FsFileDescriptor *)((int)block + index *
  6119.                            FS_MAX_FILE_DESC_SIZE);
  6120.         fileDescPtr->magic = FS_FD_MAGIC;
  6121.         fileDescPtr->flags = FS_FD_FREE;
  6122. d1041 1
  6123. a1041 1
  6124.     for (index = FS_FILE_DESC_PER_BLOCK;
  6125. d1043 1
  6126. a1043 1
  6127.          index += FS_FILE_DESC_PER_BLOCK) {
  6128. d1045 1
  6129. a1045 1
  6130.              headerPtr->fileDescOffset + (index/FS_FILE_DESC_PER_BLOCK),
  6131. d1074 1
  6132. a1074 1
  6133.     register FsFileDescriptor *fileDescPtr;
  6134. d1079 1
  6135. a1079 1
  6136.     fileDescPtr->flags = FS_FD_ALLOC;
  6137. d1109 2
  6138. a1110 2
  6139.     for (index = 1; index < FS_NUM_DIRECT_BLOCKS ; index++) {
  6140.     fileDescPtr->direct[index] = FS_NIL_INDEX;
  6141. d1112 2
  6142. a1113 2
  6143.     for (index = 0; index < FS_NUM_INDIRECT_BLOCKS ; index++) {
  6144.     fileDescPtr->indirect[index] = FS_NIL_INDEX;
  6145. d1136 1
  6146. a1136 1
  6147.     register FsFileDescriptor *fileDescPtr;
  6148. d1141 1
  6149. a1141 1
  6150.     fileDescPtr->flags = FS_FD_ALLOC;
  6151. d1170 2
  6152. a1171 2
  6153.     for (index = 0; index < FS_NUM_DIRECT_BLOCKS ; index++) {
  6154.     fileDescPtr->direct[index] = FS_NIL_INDEX;
  6155. d1173 2
  6156. a1174 2
  6157.     for (index = 0; index < FS_NUM_INDIRECT_BLOCKS ; index++) {
  6158.     fileDescPtr->indirect[index] = FS_NIL_INDEX;
  6159. d1197 1
  6160. a1197 1
  6161.     register FsFileDescriptor *fileDescPtr;
  6162. d1202 1
  6163. a1202 1
  6164.     fileDescPtr->flags = FS_FD_ALLOC;
  6165. d1207 1
  6166. a1207 1
  6167.     fileDescPtr->lastByte = FS_NUM_LOST_FOUND_BLOCKS * FS_BLOCK_SIZE - 1;
  6168. d1228 1
  6169. a1228 1
  6170.     for (index = 0; index < FS_NUM_LOST_FOUND_BLOCKS ; index++) {
  6171. d1231 2
  6172. a1232 2
  6173.     for (; index < FS_NUM_DIRECT_BLOCKS ; index++) {
  6174.     fileDescPtr->direct[index] = FS_NIL_INDEX;
  6175. d1234 2
  6176. a1235 2
  6177.     for (index = 0; index < FS_NUM_INDIRECT_BLOCKS ; index++) {
  6178.     fileDescPtr->indirect[index] = FS_NIL_INDEX;
  6179. d1258 1
  6180. a1258 1
  6181.     register FsFileDescriptor *fileDescPtr;
  6182. d1263 1
  6183. a1263 1
  6184.     fileDescPtr->flags = FS_FD_ALLOC;
  6185. d1289 2
  6186. a1290 2
  6187.     for (index = 0; index < FS_NUM_DIRECT_BLOCKS ; index++) {
  6188.     fileDescPtr->direct[index] = FS_NIL_INDEX;
  6189. d1292 2
  6190. a1293 2
  6191.     for (index = 0; index < FS_NUM_INDIRECT_BLOCKS ; index++) {
  6192.     fileDescPtr->indirect[index] = FS_NIL_INDEX;
  6193. d1316 1
  6194. a1316 1
  6195.     register FsFileDescriptor *fileDescPtr;
  6196. d1321 1
  6197. a1321 1
  6198.     fileDescPtr->flags = FS_FD_ALLOC;
  6199. d1350 2
  6200. a1351 2
  6201.     for (; index < FS_NUM_DIRECT_BLOCKS ; index++) {
  6202.     fileDescPtr->direct[index] = FS_NIL_INDEX;
  6203. d1353 2
  6204. a1354 2
  6205.     for (index = 0; index < FS_NUM_INDIRECT_BLOCKS ; index++) {
  6206.     fileDescPtr->indirect[index] = FS_NIL_INDEX;
  6207. d1377 1
  6208. a1377 1
  6209.     register FsDomainHeader *headerPtr;
  6210. d1392 1
  6211. a1392 1
  6212.      * File number 2 (FS_ROOT_FILE_NUMBER) is the root directory of the domain.
  6213. d1429 1
  6214. d1459 1
  6215. a1459 1
  6216.     register FsDomainHeader *headerPtr;
  6217. d1508 1
  6218. a1508 1
  6219.     register FsDomainHeader *headerPtr;
  6220. d1513 1
  6221. a1513 1
  6222.     FsDirEntry *dirEntryPtr;
  6223. d1520 1
  6224. a1520 1
  6225.     dirEntryPtr = (FsDirEntry *)block;
  6226. d1524 2
  6227. a1525 2
  6228.     dirEntryPtr->fileNumber = FS_ROOT_FILE_NUMBER;
  6229.     dirEntryPtr->recordLength = FsDirRecLength(length);
  6230. d1530 1
  6231. a1530 1
  6232.     dirEntryPtr = (FsDirEntry *)((int)block + offset);
  6233. d1533 2
  6234. a1534 2
  6235.     dirEntryPtr->fileNumber = FS_ROOT_FILE_NUMBER;
  6236.     dirEntryPtr->recordLength = FsDirRecLength(length);
  6237. d1543 1
  6238. a1543 1
  6239.     dirEntryPtr = (FsDirEntry *) ((int)block + offset);
  6240. d1546 1
  6241. a1546 1
  6242.     dirEntryPtr->fileNumber = FS_LOST_FOUND_FILE_NUMBER;
  6243. d1554 1
  6244. a1554 1
  6245.     dirEntryPtr->recordLength = FsDirRecLength(length);
  6246. d1556 1
  6247. a1556 1
  6248.     dirEntryPtr = (FsDirEntry *)((int)block + offset);
  6249. d1559 1
  6250. a1559 1
  6251.     dirEntryPtr->fileNumber = FS_LOST_FOUND_FILE_NUMBER + 1;
  6252. d1567 1
  6253. a1567 1
  6254.     dirEntryPtr->recordLength = FS_DIR_BLOCK_SIZE - offset;
  6255. d1569 1
  6256. a1569 1
  6257.     dirEntryPtr->recordLength = FsDirRecLength(length);
  6258. d1571 1
  6259. a1571 1
  6260.     dirEntryPtr = (FsDirEntry *)((int)block + offset);
  6261. d1574 1
  6262. a1574 1
  6263.     dirEntryPtr->fileNumber = FS_LOST_FOUND_FILE_NUMBER + 2;
  6264. d1577 1
  6265. a1577 1
  6266.     dirEntryPtr->recordLength = FS_DIR_BLOCK_SIZE - offset;
  6267. d1584 3
  6268. a1586 3
  6269.     for (dirEntryPtr = (FsDirEntry *)&block[FS_DIR_BLOCK_SIZE], i = 1; 
  6270.      i < FS_BLOCK_SIZE / FS_DIR_BLOCK_SIZE;
  6271.      i++,dirEntryPtr=(FsDirEntry *)((int)dirEntryPtr + FS_DIR_BLOCK_SIZE)) {
  6272. d1588 1
  6273. a1588 1
  6274.      dirEntryPtr->recordLength = FS_DIR_BLOCK_SIZE;
  6275. d1595 1
  6276. a1595 1
  6277.     dirEntryPtr = (FsDirEntry *)block;
  6278. d1598 1
  6279. a1598 1
  6280.     dirEntryPtr = (FsDirEntry *)((int)block + offset);
  6281. d1601 1
  6282. a1601 1
  6283.     dirEntryPtr = (FsDirEntry *)((int)block + offset);
  6284. d1605 1
  6285. a1605 1
  6286.         dirEntryPtr = (FsDirEntry *)((int)block + offset);
  6287. d1610 1
  6288. a1610 1
  6289.         dirEntryPtr = (FsDirEntry *)((int)block + offset);
  6290. d1643 1
  6291. a1643 1
  6292.     register FsDomainHeader *headerPtr;
  6293. d1648 1
  6294. a1648 1
  6295.     FsDirEntry *dirEntryPtr;
  6296. d1654 2
  6297. a1655 2
  6298.     block = (char *)malloc(FS_NUM_LOST_FOUND_BLOCKS * FS_BLOCK_SIZE);
  6299.     dirEntryPtr = (FsDirEntry *)block;
  6300. d1659 2
  6301. a1660 2
  6302.     dirEntryPtr->fileNumber = FS_LOST_FOUND_FILE_NUMBER;
  6303.     dirEntryPtr->recordLength = FsDirRecLength(length);
  6304. d1665 1
  6305. a1665 1
  6306.     dirEntryPtr = (FsDirEntry *)((int)block + offset);
  6307. d1668 2
  6308. a1669 2
  6309.     dirEntryPtr->fileNumber = FS_ROOT_FILE_NUMBER;
  6310.     dirEntryPtr->recordLength = FS_DIR_BLOCK_SIZE - offset;
  6311. d1677 3
  6312. a1679 3
  6313.     for (dirEntryPtr = (FsDirEntry *)&block[FS_DIR_BLOCK_SIZE], i = 1; 
  6314.      i < FS_NUM_LOST_FOUND_BLOCKS * FS_BLOCK_SIZE / FS_DIR_BLOCK_SIZE;
  6315.      i++,dirEntryPtr=(FsDirEntry *)((int)dirEntryPtr + FS_DIR_BLOCK_SIZE)) {
  6316. d1681 1
  6317. a1681 1
  6318.      dirEntryPtr->recordLength = FS_DIR_BLOCK_SIZE;
  6319. d1687 1
  6320. a1687 1
  6321.     dirEntryPtr = (FsDirEntry *)block;
  6322. d1690 1
  6323. a1690 1
  6324.     dirEntryPtr = (FsDirEntry *)((int)block + offset);
  6325. d1695 1
  6326. a1695 1
  6327.                 FS_NUM_LOST_FOUND_BLOCKS, block);
  6328. @
  6329.  
  6330.  
  6331. 1.12
  6332. log
  6333. @added -host option
  6334. @
  6335. text
  6336. @d11 1
  6337. a11 1
  6338. static char rcsid[] = "$Header: /sprite/src/admin/fsmake/RCS/fsmake.c,v 1.11 89/08/25 11:33:54 jhh Exp Locker: jhh $ SPRITE (Berkeley)";
  6339. d539 2
  6340. a540 2
  6341.         blocksPerCyl, geoPtr->sectorsPerTrack * geoPtr->numHeads %
  6342.             DISK_SECTORS_PER_BLOCK);
  6343. d589 2
  6344. a590 2
  6345.         blocksPerCyl * DISK_SECTORS_PER_BLOCK -
  6346.         geoPtr->sectorsPerTrack * geoPtr->numHeads);
  6347. @
  6348.  
  6349.  
  6350. 1.11
  6351. log
  6352. @changed Sys_GetMachineInfo call to Proc_GetHostIDs
  6353. @
  6354. text
  6355. @d11 1
  6356. a11 1
  6357. static char rcsid[] = "$Header: /sprite/src/admin/fsmake/RCS/fsmake.c,v 1.10 89/08/15 16:06:57 jhh Exp Locker: jhh $ SPRITE (Berkeley)";
  6358. d21 1
  6359. d52 2
  6360. d67 2
  6361. d94 2
  6362. d177 18
  6363. d237 14
  6364. a250 9
  6365.  
  6366.     /*
  6367.      * Determine where the disk is located so we can set the
  6368.      * spriteID in the header correctly.
  6369.      */
  6370.     Fs_GetAttributesID(firstPartFID, &attrs);
  6371.     if (attrs.devServerID == FS_LOCALHOST_ID) {
  6372.     Proc_GetHostIDs((int *) NULL, &spriteID);
  6373.     printf("Making filesystem for local host, ID = 0x%x\n", spriteID);
  6374. d252 2
  6375. a253 2
  6376.     spriteID = attrs.devServerID;
  6377.     printf("Making filesystem for remote host 0x%x\n", spriteID);
  6378. @
  6379.  
  6380.  
  6381. 1.10
  6382. log
  6383. @now does a variable number of boot sectors.
  6384. @
  6385. text
  6386. @d11 1
  6387. a11 1
  6388. static char rcsid[] = "$Header: /sprite/src/admin/fsmake/RCS/fsmake.c,v 1.9 89/07/13 10:44:59 jhh Exp $ SPRITE (Berkeley)";
  6389. d219 1
  6390. a219 1
  6391.     Sys_GetMachineInfo(NULL, NULL, &spriteID);
  6392. @
  6393.  
  6394.  
  6395. 1.9
  6396. log
  6397. @creates .fscheck.out
  6398. @
  6399. text
  6400. @d11 1
  6401. a11 1
  6402. static char rcsid[] = "$Header: /sprite/src/admin/fsmake/RCS/fsmake.c,v 1.8 89/06/16 08:46:10 brent Exp $ SPRITE (Berkeley)";
  6403. d23 11
  6404. d50 1
  6405. d87 2
  6406. d160 10
  6407. d258 8
  6408. a265 7
  6409.     ReturnStatus status;
  6410.     Disk_Info *diskInfoPtr;
  6411.     FsDomainHeader *headerPtr;
  6412.     FsSummaryInfo *summaryPtr;
  6413.     FsSummaryInfo *oldSummaryPtr;
  6414.     char answer[10];
  6415.     char block[DEV_BYTES_PER_SECTOR];
  6416. d276 39
  6417. a314 4
  6418.     status = Disk_SectorRead(partFID, diskInfoPtr->summarySector, 1, block);
  6419.     if (status != SUCCESS) {
  6420.     perror("Summary sector read failed");
  6421.     return status;
  6422. d316 14
  6423. a329 11
  6424.     oldSummaryPtr = (FsSummaryInfo *) block;
  6425.     if (!printOnly) {
  6426.     printf("\nYou are about to overwrite the \"%s\" filesystem.\n", 
  6427.         oldSummaryPtr->domainPrefix);
  6428.     printf("Do you really want to do this?[y/n] ");
  6429.     if (scanf("%10s",answer) != 1) {
  6430.         exit(SUCCESS);
  6431.     }
  6432.     if ((*answer != 'y') && (*answer != 'Y')) {
  6433.         exit(SUCCESS);
  6434.     }
  6435. a330 1
  6436.  
  6437. d802 1
  6438. a1467 3
  6439.     int kbytesPerCyl;
  6440.     int bitmapBytesPerCyl;
  6441.     int index;
  6442. @
  6443.  
  6444.  
  6445. 1.8
  6446. log
  6447. @Added a notion of SCSI formatting in order to
  6448. fully utilize SCSI disks.  Previously I was
  6449. throwing away lots of tracks in order to
  6450. do (unusable) fancy block skewing.
  6451. @
  6452. text
  6453. @d11 1
  6454. a11 1
  6455. static char rcsid[] = "$Header: /sprite/src/admin/fsmake/RCS/fsmake.c,v 1.6 89/03/03 17:08:18 jhh Exp $ SPRITE (Berkeley)";
  6456. d79 6
  6457. d90 1
  6458. d96 1
  6459. a133 1
  6460.     char answer[10];
  6461. a148 9
  6462.     if (!printOnly) {
  6463.     printf("The \"-write\" option will cause fsmake to overwrite the current filesystem.\nDo you really want to do this?[y/n] ");
  6464.     if (scanf("%10s",answer) != 1) {
  6465.         exit(SUCCESS);
  6466.     }
  6467.     if ((*answer != 'y') && (*answer != 'Y')) {
  6468.         exit(SUCCESS);
  6469.     }
  6470.     }
  6471. d178 10
  6472. d238 3
  6473. d251 17
  6474. d859 3
  6475. d870 3
  6476. d952 2
  6477. d1244 61
  6478. d1349 6
  6479. d1421 3
  6480. a1423 29
  6481.     /*
  6482.      * The bitmap is organized by cylinder.  There are whole number of
  6483.      * bytes in the bitmap for each cylinder.  Each bit in the bitmap
  6484.      * corresponds to 1 kbyte on the disk.
  6485.      */
  6486.     kbytesPerCyl = headerPtr->geometry.blocksPerCylinder * DISK_KBYTES_PER_BLOCK;
  6487.     bitmapBytesPerCyl = (kbytesPerCyl - 1) / BITS_PER_BYTE + 1;
  6488.     if ((kbytesPerCyl % BITS_PER_BYTE) != 0) {
  6489.     /*
  6490.      * There are bits in the last byte of the bitmap for each cylinder
  6491.      * that don't have kbytes behind them.  Set those bits here so
  6492.      * the blocks don't get allocated.
  6493.      */
  6494.     register int extraBits;
  6495.     register int mask;
  6496.  
  6497.     extraBits = kbytesPerCyl % BITS_PER_BYTE;
  6498.     /*
  6499.      * Set up a mask that has the right part filled with 1"s.
  6500.      */
  6501.     mask = 0x0;
  6502.     for ( ; extraBits < BITS_PER_BYTE ; extraBits++) {
  6503.         mask |= 1 << ((BITS_PER_BYTE - 1) - extraBits);
  6504.     }
  6505.     for (index = 0;
  6506.          index < headerPtr->dataBlocks * DISK_KBYTES_PER_BLOCK / BITS_PER_BYTE;
  6507.          index += bitmapBytesPerCyl) {
  6508.         bitmap[index + bitmapBytesPerCyl - 1] |= mask;
  6509.     }
  6510. a1424 11
  6511.     /*
  6512.      * Set the bits in the bitmap that correspond to non-existent cylinders;
  6513.      * the bitmap is allocated a whole number of blocks on the disk
  6514.      * so there are bytes at its end that don't have blocks behind them.
  6515.      */
  6516.  
  6517.     for (index = headerPtr->dataCylinders * bitmapBytesPerCyl;
  6518.      index < headerPtr->bitmapBlocks * FS_BLOCK_SIZE;
  6519.      index++) {
  6520.     bitmap[index] = 0xff;
  6521.     }
  6522. d1494 17
  6523. a1510 1
  6524.     if (!makeFile) {
  6525. d1516 1
  6526. a1516 1
  6527.     fileName = "testFile";
  6528. d1518 1
  6529. a1518 1
  6530.     dirEntryPtr->fileNumber = FS_LOST_FOUND_FILE_NUMBER + 1;
  6531. d1523 1
  6532. d1548 5
  6533. @
  6534.  
  6535.  
  6536. 1.7
  6537. log
  6538. @Eliminated the copySuperBlock option because you always want
  6539. to copy the super block.
  6540. @
  6541. text
  6542. @d2 1
  6543. a2 1
  6544.  * makeFilesystem.c --
  6545. d33 6
  6546. d57 4
  6547. d373 5
  6548. a377 1
  6549.     SetDiskGeometry(diskInfoPtr, geoPtr);
  6550. d380 108
  6551. @
  6552.  
  6553.  
  6554. 1.6
  6555. log
  6556. @fills in attachSeconds, detachSeconds, and fixCount in summary sector
  6557. @
  6558. text
  6559. @d11 1
  6560. a11 1
  6561. static char rcsid[] = "$Header: /sprite/src/admin/fsmake/RCS/fsmake.c,v 1.5 89/01/26 11:02:18 jhh Exp Locker: jhh $ SPRITE (Berkeley)";
  6562. a28 2
  6563. Boolean copySuperBlock = FALSE;    /* Copy the super block from the first
  6564.                  * disk partition to the one being formatted */
  6565. a54 2
  6566.     {OPT_TRUE, "copy", (Address)©SuperBlock,
  6567.     "Copy the super block to the partition (FALSE)"},
  6568. d237 1
  6569. a237 1
  6570.     if (copySuperBlock && partition != 0) {
  6571. @
  6572.  
  6573.  
  6574. 1.5
  6575. log
  6576. @root directory is now allocated all of block 0, rather than one fragment.
  6577. @
  6578. text
  6579. @d11 1
  6580. a11 1
  6581. static char rcsid[] = "$Header: /sprite/src/admin/fsmake/RCS/fsmake.c,v 1.4 89/01/25 13:39:46 jhh Exp Locker: jhh $ SPRITE (Berkeley)";
  6582. d737 3
  6583. @
  6584.  
  6585.  
  6586. 1.4
  6587. log
  6588. @ported to new C library, fixed a few minor bugs 
  6589. @
  6590. text
  6591. @d11 1
  6592. a11 1
  6593. static char rcsid[] = "$Header: /sprite/src/cmds.ancient/makeFilesystem/RCS/makeFilesystem.c,v 1.3 89/01/06 08:16:54 brent Exp $ SPRITE (Berkeley)";
  6594. d708 1
  6595. a708 1
  6596.      * 9 blocks are already allocated, one for the root directory,
  6597. d712 1
  6598. a712 1
  6599.                 - 9;
  6600. d869 1
  6601. a869 1
  6602.     fileDescPtr->lastByte = FS_DIR_BLOCK_SIZE-1;
  6603. d900 1
  6604. a900 1
  6605.     fileDescPtr->numKbytes = 1;
  6606. d1188 1
  6607. a1188 1
  6608.      * Set the bit corresponding to the kbyte used for the root directory
  6609. d1195 1
  6610. a1195 1
  6611.     bitmap[0] |= 0x8f;
  6612. d1274 1
  6613. d1319 11
  6614. @
  6615.  
  6616.  
  6617. 1.3
  6618. log
  6619. @Fixed include
  6620. @
  6621. text
  6622. @d11 1
  6623. a11 1
  6624. static char rcsid[] = "$Header: makeFilesystem.c,v 1.2 88/03/31 10:09:00 brent Exp $ SPRITE (Berkeley)";
  6625. a15 1
  6626. #include "io.h"
  6627. d17 4
  6628. d49 1
  6629. a49 1
  6630.     {OPT_STRING, 'D', (Address)&deviceName,
  6631. d51 1
  6632. a51 1
  6633.     {OPT_STRING, 'P', (Address)&partName,
  6634. d53 1
  6635. a53 1
  6636.     {OPT_TRUE, 'f', (Address)&makeFile,
  6637. d55 3
  6638. a57 3
  6639.     {OPT_TRUE, 'O', (Address)&overlapBlocks,
  6640.     "Overlap filesystem blocks accross track boundaries (FALSE)"},
  6641.     {OPT_TRUE, 'c', (Address)©SuperBlock,
  6642. d59 1
  6643. a59 1
  6644.     {OPT_INT, 'r', (Address)&kbytesToFileDesc,
  6645. d61 1
  6646. a61 1
  6647.     {OPT_TRUE, 't', (Address)&printOnly,
  6648. d63 1
  6649. a63 1
  6650.     {OPT_FALSE, 'W', (Address)&printOnly,
  6651. d65 1
  6652. a65 1
  6653.     {OPT_STRING, 'd', (Address)&devDirectory,
  6654. d67 1
  6655. a67 1
  6656.     {OPT_STRING, 'p', (Address)&firstPartName,
  6657. d120 1
  6658. d122 1
  6659. a122 1
  6660.     (void)Opt_Parse(&argc, argv, numOptions, optionArray);
  6661. d124 1
  6662. d126 1
  6663. a126 1
  6664.     Io_Print("Specify device name with -D option\n");
  6665. d130 1
  6666. a130 1
  6667.     Io_Print("Specify partition with -P option\n");
  6668. d134 1
  6669. a134 1
  6670.     Proc_Exit(status);
  6671. d136 9
  6672. a144 1
  6673.  
  6674. d149 6
  6675. a154 6
  6676.     String_Copy(devDirectory, firstPartitionName);    /* eg. /dev/ */
  6677.     String_Copy(devDirectory, partitionName);
  6678.     String_Cat(deviceName, firstPartitionName);        /* eg. /dev/rxy0 */
  6679.     String_Cat(deviceName, partitionName);
  6680.     String_Cat(firstPartName, firstPartitionName);    /* eg. /dev/rxy0a */
  6681.     String_Cat(partName, partitionName);        /* eg. /dev/rxy0b */
  6682. d156 5
  6683. a160 5
  6684.     status = Fs_Open(firstPartitionName, FS_READ, 0, &firstPartFID);
  6685.     if (status != SUCCESS) {
  6686.     Io_PrintStream(io_StdErr, "Can't open first partition \"%s\" <%x>\n",
  6687.                   firstPartitionName, status);
  6688.     Proc_Exit(status);
  6689. d162 4
  6690. a165 5
  6691.     status = Fs_Open(partitionName, FS_READ|FS_WRITE, 0, &partFID);
  6692.     if (status != SUCCESS) {
  6693.     Io_PrintStream(io_StdErr,"Can't open partition to format \"%s\" <%x>\n",
  6694.                   partitionName, status);
  6695.     Proc_Exit(status);
  6696. d170 1
  6697. a170 1
  6698.     Io_PrintStream(io_StdErr,
  6699. d172 1
  6700. a172 1
  6701.     Proc_Exit(FAILURE);
  6702. d182 1
  6703. a182 1
  6704.     Io_Print("Making filesystem for local host, ID = 0x%x\n", spriteID);
  6705. d185 1
  6706. a185 1
  6707.     Io_Print("Making filesystem for remote host 0x%x\n", spriteID);
  6708. d187 1
  6709. a187 1
  6710.     Io_Print("MakeFilesystem based on 4K filesystem blocks\n");
  6711. d190 5
  6712. a194 5
  6713.     Io_Flush(io_StdErr);
  6714.     Io_Flush(io_StdOut);
  6715.     (void)Fs_Close(firstPartFID);
  6716.     (void)Fs_Close(partFID);
  6717.     Proc_Exit(status);
  6718. d221 1
  6719. a221 2
  6720.     register int numBlocks;
  6721.     BasicDiskInfo *diskInfoPtr;
  6722. d229 3
  6723. a231 2
  6724.     diskInfoPtr = ReadBasicDiskInfo(firstPartFID, partition);
  6725.     if (diskInfoPtr == (BasicDiskInfo *)0) {
  6726. d235 2
  6727. a236 2
  6728.     headerPtr = (FsDomainHeader *) Mem_Alloc(diskInfoPtr->numDomainSectors *
  6729.                          DEV_BYTES_PER_SECTOR);
  6730. d238 1
  6731. a238 1
  6732.     PrintDomainHeader(headerPtr);
  6733. d244 1
  6734. a244 2
  6735.         Io_PrintStream(io_StdErr, "CopySuperBlock failed <%x>\n",
  6736.                       status);
  6737. d248 1
  6738. a248 1
  6739.     status = SectorWrite(partFID, diskInfoPtr->domainSector,
  6740. d251 1
  6741. a251 2
  6742.         Io_PrintStream(io_StdErr, "DomainHeader write failed <%x>\n",
  6743.                       status);
  6744. d255 1
  6745. a255 1
  6746.     summaryPtr = (FsSummaryInfo *) Mem_Alloc(DEV_BYTES_PER_SECTOR);
  6747. d257 1
  6748. a257 1
  6749.     PrintSummaryInfo(summaryPtr);
  6750. d259 1
  6751. a259 1
  6752.     status = SectorWrite(partFID, diskInfoPtr->summarySector, 1,
  6753. d262 1
  6754. a262 2
  6755.         Io_PrintStream(io_StdErr, "DomainHeader write failed <%x>\n",
  6756.                       status);
  6757. d269 1
  6758. a269 1
  6759.     Io_PrintStream(io_StdErr, "WriteFileDesc failed <%x>\n", status);
  6760. d274 1
  6761. a274 1
  6762.     Io_PrintStream(io_StdErr, "WriteBitmap failed <%x>\n", status);
  6763. d279 1
  6764. a279 1
  6765.     Io_PrintStream(io_StdErr, "WriteRootDirectory failed <%x>\n", status);
  6766. d284 1
  6767. a284 2
  6768.     Io_PrintStream(io_StdErr, "WriteLostFoundDirectory failed <%x>\n", 
  6769.             status);
  6770. d314 1
  6771. a314 1
  6772.     block = (char *)Mem_Alloc(DEV_BYTES_PER_SECTOR);
  6773. d316 1
  6774. a316 1
  6775.     status = SectorRead(firstPartFID, 0, 1, block);
  6776. d320 1
  6777. a320 1
  6778.     status = SectorWrite(partFID, 0, 1, block);
  6779. d342 1
  6780. a342 1
  6781.     BasicDiskInfo *diskInfoPtr;    /* Information from the super block */
  6782. a346 1
  6783.     ReturnStatus status;    /* General return code. */
  6784. d354 1
  6785. a354 1
  6786.      * the host's spriteID if reverse arp couldn't find a host ID.  The
  6787. d356 1
  6788. a356 1
  6789.      * domain header applies to.  For example, both the 'a' and 'c' partitions
  6790. d395 1
  6791. a395 1
  6792.     register BasicDiskInfo *diskInfoPtr;/* Basic geometry information */
  6793. d425 2
  6794. a426 2
  6795.         extraSectors = geoPtr->sectorsPerTrack % SECTORS_PER_BLOCK;
  6796.         if (extraSectors < SECTORS_PER_BLOCK/4) {
  6797. d434 2
  6798. a435 2
  6799.         offsetIncrement = SECTORS_PER_BLOCK/4;
  6800.         } else if (extraSectors < SECTORS_PER_BLOCK/2) {
  6801. d441 2
  6802. a442 2
  6803.         offsetIncrement = SECTORS_PER_BLOCK * 3/4;
  6804.         } else if (extraSectors < SECTORS_PER_BLOCK * 3/4) {
  6805. d448 1
  6806. a448 1
  6807.         offsetIncrement = SECTORS_PER_BLOCK/2;
  6808. d455 1
  6809. a455 1
  6810.         offsetIncrement = SECTORS_PER_BLOCK/4;
  6811. d467 3
  6812. a469 3
  6813.         offsetIncrement = SECTORS_PER_BLOCK/2;
  6814.         if ((geoPtr->sectorsPerTrack % SECTORS_PER_BLOCK) <
  6815.               SECTORS_PER_BLOCK/2) {
  6816. d480 1
  6817. a480 1
  6818.     Io_Print("overlap %s, offsetIncrement %d\n", (overlap ? "TRUE" : "FALSE"),
  6819. d489 1
  6820. a489 1
  6821.     if (extraSectors >= SECTORS_PER_BLOCK) {
  6822. d495 2
  6823. a496 2
  6824.         offset += SECTORS_PER_BLOCK;
  6825.         extraSectors -= SECTORS_PER_BLOCK;
  6826. d553 1
  6827. a553 1
  6828.     offsetIncrement = SECTORS_PER_BLOCK / tracksPerSet;
  6829. d582 1
  6830. a582 1
  6831.     register BasicDiskInfo *diskInfoPtr;
  6832. a593 1
  6833.     int index;            /* Array index */
  6834. d607 1
  6835. a607 1
  6836.     Io_Print("Reserving %d blocks for domain header, etc.\n",
  6837. d620 1
  6838. a620 1
  6839.         numFiles = numBlocks * KBYTES_PER_BLOCK / kbytesToFileDesc;
  6840. d622 1
  6841. a622 1
  6842.     numFiles          &= ~(FILE_DESC_PER_BLOCK-1);
  6843. d633 2
  6844. a634 2
  6845.     numBlocks          -= numFiles / FILE_DESC_PER_BLOCK;
  6846.     offset              += numFiles / FILE_DESC_PER_BLOCK;
  6847. d645 1
  6848. a645 1
  6849.     bitmapBytes          = (headerPtr->dataBlocks * KBYTES_PER_BLOCK -
  6850. d662 1
  6851. a662 1
  6852.         numFiles -= numBlocksNeeded * FILE_DESC_PER_BLOCK;
  6853. d673 1
  6854. a673 1
  6855.         numFiles += extraBlocks * FILE_DESC_PER_BLOCK;
  6856. d699 1
  6857. a699 1
  6858.     BasicDiskInfo *diskInfoPtr;    /* Information from the super block */
  6859. a702 1
  6860.     ReturnStatus status;    /* General return code. */
  6861. d704 1
  6862. a704 1
  6863.     Byte_Zero(DEV_BYTES_PER_SECTOR, (Address)summaryPtr);
  6864. d706 1
  6865. a706 1
  6866.     String_Copy("(new domain)", summaryPtr->domainPrefix);
  6867. d727 1
  6868. a727 1
  6869.      * recorded on disk so servers re-attach disks under the same 'name'.
  6870. d734 1
  6871. a734 1
  6872.      * safely 'sync'ed to disk upon shutdown.
  6873. d767 1
  6874. a767 1
  6875.     status = BlockWrite(partFID, headerPtr, headerPtr->fdBitmapOffset,
  6876. d779 2
  6877. a780 2
  6878.     block = (char *)Mem_Alloc(FS_BLOCK_SIZE);
  6879.     Byte_Zero(FS_BLOCK_SIZE, block);
  6880. d782 1
  6881. a782 1
  6882.          index < FILE_DESC_PER_BLOCK;
  6883. d806 1
  6884. a806 1
  6885.     status = BlockWrite(partFID, headerPtr, headerPtr->fileDescOffset,
  6886. d814 1
  6887. a814 1
  6888.     Byte_Zero(FS_BLOCK_SIZE, block);
  6889. d816 1
  6890. a816 1
  6891.          index < FILE_DESC_PER_BLOCK;
  6892. d826 1
  6893. a826 1
  6894.     for (index = FILE_DESC_PER_BLOCK;
  6895. d828 3
  6896. a830 3
  6897.          index += FILE_DESC_PER_BLOCK) {
  6898.         status = BlockWrite(partFID, headerPtr,
  6899.              headerPtr->fileDescOffset + (index/FILE_DESC_PER_BLOCK),
  6900. a1102 1
  6901.     ReturnStatus status;
  6902. d1107 1
  6903. a1107 1
  6904.      * Allocate and initialize the bitmap to all 0's to mean all free.
  6905. d1109 1
  6906. a1109 1
  6907.     bitmap = (char *)Mem_Alloc(headerPtr->fdBitmapBlocks *
  6908. d1111 1
  6909. a1111 1
  6910.     Byte_Zero(headerPtr->fdBitmapBlocks * FS_BLOCK_SIZE, (Address)bitmap);
  6911. d1152 1
  6912. a1152 1
  6913.     PrintFileDescBitmap(headerPtr, bitmap);
  6914. d1185 2
  6915. a1186 2
  6916.     bitmap = (char *)Mem_Alloc(headerPtr->bitmapBlocks * FS_BLOCK_SIZE);
  6917.     Byte_Zero(headerPtr->bitmapBlocks * FS_BLOCK_SIZE, bitmap);
  6918. d1202 1
  6919. a1202 1
  6920.     kbytesPerCyl = headerPtr->geometry.blocksPerCylinder * KBYTES_PER_BLOCK;
  6921. d1215 1
  6922. a1215 1
  6923.      * Set up a mask that has the right part filled with 1's.
  6924. d1222 1
  6925. a1222 1
  6926.          index < headerPtr->dataBlocks * KBYTES_PER_BLOCK / BITS_PER_BYTE;
  6927. d1239 1
  6928. a1239 1
  6929.     PrintDataBlockBitmap(headerPtr, bitmap);
  6930. d1242 1
  6931. a1242 1
  6932.     status = BlockWrite(partFID, headerPtr, headerPtr->bitmapOffset,
  6933. d1259 1
  6934. a1259 1
  6935.  *    Write the root directory's data block.
  6936. d1275 1
  6937. a1275 1
  6938.     block = (char *)Mem_Alloc(FS_BLOCK_SIZE);
  6939. d1279 1
  6940. a1279 1
  6941.     length = String_Length(fileName);
  6942. d1283 1
  6943. a1283 1
  6944.     String_Copy(fileName, dirEntryPtr->fileName);
  6945. d1288 1
  6946. a1288 1
  6947.     length = String_Length(fileName);
  6948. d1292 1
  6949. a1292 1
  6950.     String_Copy(fileName, dirEntryPtr->fileName);
  6951. d1301 1
  6952. a1301 1
  6953.     length = String_Length(fileName);
  6954. d1304 1
  6955. a1304 1
  6956.     String_Copy(fileName, dirEntryPtr->fileName);
  6957. d1313 1
  6958. a1313 1
  6959.     length = String_Length(fileName);
  6960. d1316 1
  6961. a1316 1
  6962.     String_Copy(fileName, dirEntryPtr->fileName);
  6963. d1321 1
  6964. a1321 1
  6965.     Io_Print("Root Directory\n");
  6966. d1324 1
  6967. a1324 1
  6968.     PrintDirEntry(dirEntryPtr);
  6969. d1327 4
  6970. a1330 1
  6971.     PrintDirEntry(dirEntryPtr);
  6972. d1334 1
  6973. a1334 1
  6974.         PrintDirEntry(dirEntryPtr);
  6975. d1343 1
  6976. a1343 1
  6977.     status = BlockWrite(partFID, headerPtr, headerPtr->dataOffset, 1,
  6978. d1360 1
  6979. a1360 1
  6980.  *    Write the root directory's data block.
  6981. d1377 1
  6982. a1377 1
  6983.     block = (char *)Mem_Alloc(FS_NUM_LOST_FOUND_BLOCKS * FS_BLOCK_SIZE);
  6984. d1381 1
  6985. a1381 1
  6986.     length = String_Length(fileName);
  6987. d1385 1
  6988. a1385 1
  6989.     String_Copy(fileName, dirEntryPtr->fileName);
  6990. d1390 1
  6991. a1390 1
  6992.     length = String_Length(fileName);
  6993. d1394 1
  6994. a1394 1
  6995.     String_Copy(fileName, dirEntryPtr->fileName);
  6996. d1408 1
  6997. a1408 1
  6998.     Io_Print("Lost+found Directory\n");
  6999. d1411 1
  7000. a1411 1
  7001.     PrintDirEntry(dirEntryPtr);
  7002. d1414 1
  7003. a1414 1
  7004.     PrintDirEntry(dirEntryPtr);
  7005. d1417 1
  7006. a1417 1
  7007.     status = BlockWrite(partFID, headerPtr, headerPtr->dataOffset + 1,
  7008. @
  7009.  
  7010.  
  7011. 1.2
  7012. log
  7013. @Added bad block file descriptor and summary sector
  7014. @
  7015. text
  7016. @d11 1
  7017. a11 1
  7018. static char rcsid[] = "$Header: makeFilesystem.c,v 1.1 87/10/20 11:01:23 brent Exp $ SPRITE (Berkeley)";
  7019. d17 1
  7020. a17 1
  7021. #include "fsDisk.h"
  7022. @
  7023.  
  7024.  
  7025. 1.1
  7026. log
  7027. @Initial revision
  7028. @
  7029. text
  7030. @d11 1
  7031. a11 1
  7032. static char rcsid[] = "$Header: makeFilesystem.c,v 1.7 87/07/14 11:43:34 brent Exp $ SPRITE (Berkeley)";
  7033. d77 1
  7034. d225 1
  7035. a225 1
  7036.     SetDomainHeader(diskInfoPtr, headerPtr, spriteID);
  7037. d333 1
  7038. a333 1
  7039. SetDomainHeader(diskInfoPtr, headerPtr, spriteID)
  7040. d337 1
  7041. d346 7
  7042. a352 3
  7043.      * Only the device.serverID from the disk is used.  It is examined
  7044.      * during boot to discover the host's spriteID if reverse arp
  7045.      * couldn't find a host ID.
  7046. d356 1
  7047. a356 1
  7048.     headerPtr->device.unit = -1;
  7049. d717 1
  7050. a717 1
  7051.      * The summary state is unused.
  7052. d720 12
  7053. d769 4
  7054. a772 1
  7055.      * Make the first block of file descriptors.
  7056. d782 1
  7057. a782 1
  7058.     if (index < ROOT_FILE_NUMBER) {
  7059. d784 3
  7060. a786 1
  7061.     } else if (index == ROOT_FILE_NUMBER) {
  7062. d902 61
  7063. d1112 1
  7064. a1112 1
  7065.      * File number 2 (ROOT_FILE_NUMBER) is the root directory of the domain.
  7066. d1276 1
  7067. a1276 1
  7068.     dirEntryPtr->fileNumber = ROOT_FILE_NUMBER;
  7069. d1285 1
  7070. a1285 1
  7071.     dirEntryPtr->fileNumber = ROOT_FILE_NUMBER;
  7072. @
  7073.